This checkin enables mozilla to support the printing of selection, the printing of page ranges, and

the printing of headers and footers.
Printing of selection is implemented by the frames figuring out if they are in the selection and painting
if they or not they they don't paint. This also only allows the printing of the first page of
selections, alothough it is well documented where this is implemeted so it can be removed.
Bugs 63426, 31218, 61075 r=dcone,kmcclusk,erik,buster sr=waterson
This commit is contained in:
rods%netscape.com 2001-01-27 14:09:34 +00:00
parent bb40b036ad
commit 99666eed8c
109 changed files with 5659 additions and 660 deletions

View File

@ -297,6 +297,7 @@ sub ProcessJarManifests()
CreateJarFromManifest(":mozilla:extensions:wallet:jar.mn", $chrome_dir, \%jars);
CreateJarFromManifest(":mozilla:intl:uconv:src:jar.mn", $chrome_dir, \%jars);
CreateJarFromManifest(":mozilla:layout:html:forms:src:jar.mn", $chrome_dir, \%jars);
CreateJarFromManifest(":mozilla:layout:html:base:src:jar.mn", $chrome_dir, \%jars);
CreateJarFromManifest(":mozilla:mailnews:jar.mn", $chrome_dir, \%jars);
CreateJarFromManifest(":mozilla:netwerk:resources:jar.mn", $chrome_dir, \%jars);
CreateJarFromManifest(":mozilla:profile:pref-migrator:resources:jar.mn", $chrome_dir, \%jars);

View File

@ -87,6 +87,13 @@
#include "nsIEventQueueService.h"
#include "nsIEventQueue.h"
// Print Options
#include "nsIPrintOptions.h"
#include "nsGfxCIID.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID);
#include "nsHTMLAtoms.h" // XXX until atoms get factored into nsLayoutAtoms
//focus
#include "nsIDOMEventReceiver.h"
#include "nsIDOMFocusListener.h"
@ -248,12 +255,16 @@ private:
const nsRect& aBounds);
nsresult GetDocumentSelection(nsISelection **aSelection);
nsresult GetDocumentSelection(nsIPresShell * aPresShell, nsISelection **aSelection);
nsresult FindFrameSetWithIID(nsIContent * aParentContent, const nsIID& aIID);
PRBool IsThereASelection();
//
// The following three methods are used for printing...
//
void DocumentReadyForPrinting();
//nsresult PrintSelection(nsIDeviceContextSpec * aDevSpec);
nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc);
static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent);
static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent);
@ -297,6 +308,8 @@ protected:
nsIViewManager *mPrintVM;
nsIView *mPrintView;
FILE *mFilePointer; // a file where information can go to when printing
nsIDocument *mSelectionDoc;
nsIDocShell *mSelectionDocShell;
nsCOMPtr<nsIPrintListener> mPrintListener; // An observer for printing...
@ -339,6 +352,7 @@ DocumentViewerImpl::DocumentViewerImpl()
mEnableRendering = PR_TRUE;
mFilePointer = nsnull;
mPrintListener = nsnull;
mSelectionDoc = nsnull;
}
DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext)
@ -879,6 +893,386 @@ DocumentViewerImpl::FindFrameSetWithIID(nsIContent * aParentContent, const nsIID
return NS_ERROR_FAILURE;
}
//---------------------------------------------------------------
//---------------------------------------------------------------
//-- Debug helper routines
//---------------------------------------------------------------
//---------------------------------------------------------------
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
/** ---------------------------------------------------
* Dumps Frames for Printing
*/
static void DumpFrames(FILE* out,
nsIPresContext* aPresContext,
nsIRenderingContext * aRendContext,
nsIFrame * aFrame,
PRInt32 aLevel)
{
nsIFrame * child;
aFrame->FirstChild(aPresContext, nsnull, &child);
while (child != nsnull) {
for (PRInt32 i=0;i<aLevel;i++) {
fprintf(out, " ");
}
nsAutoString tmp;
nsIFrameDebug* frameDebug;
if (NS_SUCCEEDED(child->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) {
frameDebug->GetFrameName(tmp);
}
fputs(tmp, out);
nsFrameState state;
child->GetFrameState(&state);
PRBool isSelected;
if (NS_SUCCEEDED(child->IsVisibleForPainting(aPresContext, *aRendContext, PR_TRUE, &isSelected))) {
fprintf(out, " %p %s", child, isSelected?"VIS":"UVS");
nsRect rect;
child->GetRect(rect);
fprintf(out, "[%d,%d,%d,%d] ", rect.x, rect.y, rect.width, rect.height);
nsIView * view;
child->GetView(aPresContext, &view);
fprintf(out, "v: %p ", view);
fprintf(out, "\n");
DumpFrames(out, aPresContext, aRendContext, child, aLevel+1);
child->GetNextSibling(&child);
}
}
}
/** ---------------------------------------------------
* Helper function needed for "DumpViews"
*/
static nsIPresShell*
GetPresShellFor(nsIDocShell* aDocShell)
{
nsIPresShell* shell = nsnull;
if (nsnull != aDocShell) {
nsIContentViewer* cv = nsnull;
aDocShell->GetContentViewer(&cv);
if (nsnull != cv) {
nsIDocumentViewer* docv = nsnull;
cv->QueryInterface(NS_GET_IID(nsIDocumentViewer), (void**) &docv);
if (nsnull != docv) {
nsIPresContext* cx;
docv->GetPresContext(cx);
if (nsnull != cx) {
cx->GetShell(&shell);
NS_RELEASE(cx);
}
NS_RELEASE(docv);
}
NS_RELEASE(cv);
}
}
return shell;
}
/** ---------------------------------------------------
* Dumps the Views from the DocShell
*/
static void
DumpViews(nsIDocShell* aDocShell, FILE* out)
{
if (nsnull != aDocShell) {
fprintf(out, "docshell=%p \n", aDocShell);
nsIPresShell* shell = GetPresShellFor(aDocShell);
if (nsnull != shell) {
nsCOMPtr<nsIViewManager> vm;
shell->GetViewManager(getter_AddRefs(vm));
if (vm) {
nsIView* root;
vm->GetRootView(root);
if (nsnull != root) {
root->List(out);
}
}
NS_RELEASE(shell);
}
else {
fputs("null pres shell\n", out);
}
// dump the views of the sub documents
PRInt32 i, n;
nsCOMPtr<nsIDocShellTreeNode> docShellAsNode(do_QueryInterface(aDocShell));
docShellAsNode->GetChildCount(&n);
for (i = 0; i < n; i++) {
nsCOMPtr<nsIDocShellTreeItem> child;
docShellAsNode->GetChildAt(i, getter_AddRefs(child));
nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
if (childAsShell) {
DumpViews(childAsShell, out);
}
}
}
}
/** ---------------------------------------------------
* Dumps the Views and Frames
*/
void DumpLayoutData(nsIPresContext* aPresContext,
nsIDeviceContext * aDC,
nsIFrame * aRootFrame,
nsIWebShell * aWebShell)
{
// Dump all the frames and view to a a file
FILE * fd = fopen("dump.txt", "w");
if (fd) {
fprintf(fd, "--------------- Frames ----------------\n");
nsCOMPtr<nsIRenderingContext> renderingContext;
aDC->CreateRenderingContext(*getter_AddRefs(renderingContext));
DumpFrames(fd, aPresContext, renderingContext, aRootFrame, 0);
fprintf(fd, "---------------------------------------\n\n");
fprintf(fd, "--------------- Views From Root Frame----------------\n");
nsIView * v;
aRootFrame->GetView(aPresContext, &v);
if (v) {
v->List(fd);
} else {
printf("View is null!\n");
}
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aWebShell));
if (docShell) {
fprintf(fd, "--------------- All Views ----------------\n");
DumpViews(docShell, fd);
fprintf(fd, "---------------------------------------\n\n");
}
fclose(fd);
}
}
#endif
//---------------------------------------------------------------
//---------------------------------------------------------------
//-- End of debug helper routines
//---------------------------------------------------------------
//---------------------------------------------------------------
/** ---------------------------------------------------
* Giving a child frame it searches "up" the tree until it
* finds a "Page" frame.
*/
static nsIFrame * GetPageFrame(nsIFrame * aFrame)
{
nsIFrame * frame = aFrame;
while (frame != nsnull) {
nsCOMPtr<nsIAtom> type;
frame->GetFrameType(getter_AddRefs(type));
if (type.get() == nsLayoutAtoms::pageFrame) {
return frame;
}
frame->GetParent(&frame);
}
return nsnull;
}
/** ---------------------------------------------------
* Find by checking content's tag type
*/
static nsIFrame * FindFrameByType(nsIPresContext* aPresContext,
nsIFrame * aParentFrame,
nsIAtom * aType,
nsRect& aRect,
nsRect& aChildRect)
{
nsIFrame * child;
nsRect rect;
aParentFrame->GetRect(rect);
aRect.x += rect.x;
aRect.y += rect.y;
aParentFrame->FirstChild(aPresContext, nsnull, &child);
while (child != nsnull) {
nsCOMPtr<nsIContent> content;
child->GetContent(getter_AddRefs(content));
if (content) {
nsCOMPtr<nsIAtom> type;
content->GetTag(*getter_AddRefs(type));
if (type.get() == aType) {
nsRect r;
child->GetRect(r);
aChildRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height);
aRect.x -= rect.x;
aRect.y -= rect.y;
return child;
}
}
nsIFrame * fndFrame = FindFrameByType(aPresContext, child, aType, aRect, aChildRect);
if (fndFrame != nsnull) {
return fndFrame;
}
child->GetNextSibling(&child);
}
aRect.x -= rect.x;
aRect.y -= rect.y;
return nsnull;
}
/** ---------------------------------------------------
* Find by checking frames type
*/
static nsresult FindSelectionBounds(nsIPresContext* aPresContext,
nsIRenderingContext& aRC,
nsIFrame * aParentFrame,
nsRect& aRect,
nsIFrame *& aStartFrame,
nsRect& aStartRect,
nsIFrame *& aEndFrame,
nsRect& aEndRect)
{
nsIFrame * child;
aParentFrame->FirstChild(aPresContext, nsnull, &child);
nsRect rect;
aParentFrame->GetRect(rect);
aRect.x += rect.x;
aRect.y += rect.y;
while (child != nsnull) {
nsFrameState state;
child->GetFrameState(&state);
// only leaf frames have this bit flipped
// then check the hard way
PRBool isSelected = (state & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (isSelected) {
if (NS_FAILED(child->IsVisibleForPainting(aPresContext, aRC, PR_TRUE, &isSelected))) {
return NS_ERROR_FAILURE;
}
}
if (isSelected) {
nsRect r;
child->GetRect(r);
if (aStartFrame == nsnull) {
aStartFrame = child;
aStartRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height);
} else {
child->GetRect(r);
aEndFrame = child;
aEndRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height);
}
}
FindSelectionBounds(aPresContext, aRC, child, aRect, aStartFrame, aStartRect, aEndFrame, aEndRect);
child->GetNextSibling(&child);
}
aRect.x -= rect.x;
aRect.y -= rect.y;
return NS_OK;
}
/** ---------------------------------------------------
* This method finds the starting and ending page numbers
* of the selection and also returns rect for each where
* the x,y of the rect is relative to the very top of the
* frame tree (absolutely positioned)
*/
static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell,
nsIPresContext* aPresContext,
nsIRenderingContext& aRC,
nsISelection* aSelection,
nsIPageSequenceFrame* aPageSeqFrame,
nsIFrame** aStartFrame,
PRInt32& aStartPageNum,
nsRect& aStartRect,
nsIFrame** aEndFrame,
PRInt32& aEndPageNum,
nsRect& aEndRect)
{
nsIFrame * seqFrame;
if (NS_FAILED(aPageSeqFrame->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) {
return NS_ERROR_FAILURE;
}
nsIFrame * startFrame = nsnull;
nsIFrame * endFrame = nsnull;
nsRect rect;
seqFrame->GetRect(rect);
// start out with the sequence frame and search the entire frame tree
// capturing the the starting and ending child frames of the selection
// and their rects
FindSelectionBounds(aPresContext, aRC, seqFrame, rect, startFrame, aStartRect, endFrame, aEndRect);
#ifdef DEBUG_rods
printf("Start Frame: %p\n", startFrame);
printf("End Frame: %p\n", endFrame);
#endif
// initial the page numbers here
// in case we don't find and frames
aStartPageNum = -1;
aEndPageNum = -1;
nsIFrame * startPageFrame;
nsIFrame * endPageFrame;
// check to make sure we found a starting frame
if (startFrame != nsnull) {
// Now search up the tree to find what page the
// start/ending selections frames are on
//
// Check to see if start should be same as end if
// the end frame comes back null
if (endFrame == nsnull) {
// XXX the "GetPageFrame" step could be integrated into
// the FindSelectionBounds step, but walking up to find
// the parent of a child frame isn't expensive and it makes
// FindSelectionBounds a little easier to understand
startPageFrame = GetPageFrame(startFrame);
endPageFrame = startPageFrame;
aEndRect = aStartRect;
} else {
startPageFrame = GetPageFrame(startFrame);
endPageFrame = GetPageFrame(endFrame);
}
} else {
return NS_ERROR_FAILURE;
}
#ifdef DEBUG_rods
printf("Start Page: %p\n", startPageFrame);
printf("End Page: %p\n", endPageFrame);
// dump all the pages and their pointers
{
PRInt32 pageNum = 1;
nsIFrame * child;
seqFrame->FirstChild(aPresContext, nsnull, &child);
while (child != nsnull) {
printf("Page: %d - %p\n", pageNum, child);
pageNum++;
child->GetNextSibling(&child);
}
}
#endif
// Now that we have the page frames
// find out what the page numbers are for each frame
PRInt32 pageNum = 1;
nsIFrame * page;
seqFrame->FirstChild(aPresContext, nsnull, &page);
while (page != nsnull) {
if (page == startPageFrame) {
aStartPageNum = pageNum;
}
if (page == endPageFrame) {
aEndPageNum = pageNum;
}
pageNum++;
page->GetNextSibling(&page);
}
#ifdef DEBUG_rods
printf("Start Page No: %d\n", aStartPageNum);
printf("End Page No: %d\n", aEndPageNum);
#endif
*aStartFrame = startPageFrame;
*aEndFrame = endPageFrame;
return NS_OK;
}
//-------------------------------------------------------
nsresult
DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
nsIDeviceContext * aDContext)
@ -889,7 +1283,6 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
nsCOMPtr<nsIStyleSet> ss;
nsCOMPtr<nsIViewManager> vm;
PRInt32 width, height;
nsIView *view;
nsresult rv;
PRInt32 count,i;
nsCOMPtr<nsIContentViewer> viewer;
@ -922,7 +1315,10 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
nsCOMPtr<nsIDocument> doc;
shell->GetDocument(getter_AddRefs(doc));
if (doc) {
nsCOMPtr<nsIContent> rootContent = getter_AddRefs(mDocument->GetRootContent());
if (mSelectionDoc) {
doc = mSelectionDoc;
}
nsCOMPtr<nsIContent> rootContent = getter_AddRefs(doc->GetRootContent());
if (rootContent) {
if (NS_SUCCEEDED(FindFrameSetWithIID(rootContent, NS_GET_IID(nsIDOMHTMLFrameSetElement)))) {
doesContainFrameSet = PR_TRUE;
@ -955,6 +1351,16 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
NS_ENSURE_SUCCESS( aDContext->BeginDocument(), NS_ERROR_FAILURE );
aDContext->GetDeviceSurfaceDimensions(width, height);
// XXX - Hack Alert
// OK, so ther eis a selection, we will print the entire selection
// on one page and then crop the page.
// This means you can never print any selection that is longer than one page
// put it keeps it from page breaking in the middle of your print of the selection
// (see also nsSimplePageSequence.cpp)
if (IsThereASelection()) {
height = 0x0FFFFFFF;
}
nsCOMPtr<nsIPresContext> cx;
nsCOMPtr<nsIPrintContext> printcon;
rv = NS_NewPrintContext(getter_AddRefs(printcon));
@ -992,17 +1398,18 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
nsRect tbounds = nsRect(0, 0, width, height);
// Create a child window of the parent that is our "root view/window"
rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&view);
nsIView* rootView;
rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&rootView);
if (NS_FAILED(rv)) {
return rv;
}
rv = view->Init(vm, tbounds, nsnull);
rv = rootView->Init(vm, tbounds, nsnull);
if (NS_FAILED(rv)) {
return rv;
}
// Setup hierarchical relationship in view manager
vm->SetRootView(view);
vm->SetRootView(rootView);
ps->Init(mDocument, cx, vm, ss);
@ -1018,10 +1425,30 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE);
presShell->CaptureHistoryState(getter_AddRefs(layoutState),PR_TRUE);
ps->BeginObservingDocument();
//lay it out...
ps->InitialReflow(width, height);
// Transfer Selection Ranges to the new Print PresShell
nsCOMPtr<nsISelection> selection;
nsCOMPtr<nsISelection> selectionPS;
GetDocumentSelection(getter_AddRefs(selection));
if (selection) {
GetDocumentSelection(ps, getter_AddRefs(selectionPS));
if (selectionPS) {
PRInt32 cnt;
selection->GetRangeCount(&cnt);
PRInt32 inx;
for (inx=0;inx<cnt;inx++) {
nsCOMPtr<nsIDOMRange> range;
if (NS_SUCCEEDED(selection->GetRangeAt(inx, getter_AddRefs(range)))) {
selectionPS->AddRange(range);
}
}
}
}
// update the history from the old presentation shell
nsCOMPtr<nsIFrameManager> fm;
rv = ps->GetFrameManager(getter_AddRefs(fm));
@ -1034,8 +1461,8 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
// Ask the page sequence frame to print all the pages
nsIPageSequenceFrame* pageSequence;
nsPrintOptions options;
//
ps->GetPageSequenceFrame(&pageSequence);
NS_ASSERTION(nsnull != pageSequence, "no page sequence frame");
@ -1051,7 +1478,97 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
}
fclose(mFilePointer);
} else {
pageSequence->Print(cx, options, nsnull);
nsIFrame* rootFrame;
ps->GetRootFrame(&rootFrame);
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
DumpLayoutData(cx, aDContext, rootFrame, aParent);
#endif
nsPrintRange printRangeType = ePrintRange_AllPages;
NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv);
if (NS_SUCCEEDED(rv) && printService) {
PRInt32 printType;
printService->GetPrintRange(&printType);
printRangeType = (nsPrintRange)printType;
// get the document title
const nsString* docTitle = mDocument->GetDocumentTitle();
PRUnichar * docStr = docTitle->ToNewUnicode();
printService->SetTitle(docStr);
nsMemory::Free(docStr);
// Get Document URL String
nsCOMPtr<nsIURI> url(getter_AddRefs(mDocument->GetDocumentURL()));
char * urlCStr;
url->GetSpec(&urlCStr);
nsAutoString urlStr;
urlStr.AssignWithConversion(urlCStr);
PRUnichar * urlUStr = urlStr.ToNewUnicode();
printService->SetURL(urlUStr);
nsMemory::Free(urlUStr);
nsMemory::Free(urlCStr);
if (ePrintRange_Selection == printRangeType) {
cx->SetIsRenderingOnlySelection(PR_TRUE);
// temporarily creating rendering context
// which is needed to dinf the selection frames
nsCOMPtr<nsIRenderingContext> rc;
aDContext->CreateRenderingContext(*getter_AddRefs(rc));
// find the starting and ending page numbers
// via the selection
nsIFrame* startFrame;
nsIFrame* endFrame;
PRInt32 startPageNum;
PRInt32 endPageNum;
nsRect startRect;
nsRect endRect;
rv = GetPageRangeForSelection(ps, cx, *rc, selectionPS, pageSequence,
&startFrame, startPageNum, startRect,
&endFrame, endPageNum, endRect);
if (NS_SUCCEEDED(rv)) {
printService->SetPageRange(startPageNum, endPageNum);
if (startPageNum == endPageNum) {
nsIFrame * seqFrame;
if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) {
return NS_ERROR_FAILURE;
}
nsRect rect(0,0,0,0);
nsRect areaRect;
nsIFrame * areaFrame = FindFrameByType(cx, startFrame, nsHTMLAtoms::body, rect, areaRect);
if (areaFrame) {
areaRect.y = areaRect.y - startRect.y;
areaFrame->SetRect(cx, areaRect);
}
}
}
}
nsIFrame * seqFrame;
if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) {
return NS_ERROR_FAILURE;
}
nsRect srect;
seqFrame->GetRect(srect);
nsRect r;
rootView->GetBounds(r);
r.height = srect.height;
rootView->SetBounds(r);
rootFrame->GetRect(r);
r.height = srect.height;
rootFrame->SetRect(cx, r);
pageSequence->Print(cx, printService, nsnull);
} else {
// not sure what to do here!
return NS_ERROR_FAILURE;
}
}
aDContext->EndDocument();
@ -1287,17 +1804,23 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget,
return rv;
}
nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection)
nsresult DocumentViewerImpl::GetDocumentSelection(nsIPresShell * aPresShell, nsISelection **aSelection)
{
if (!aSelection) return NS_ERROR_NULL_POINTER;
if (!mPresShell) return NS_ERROR_NOT_INITIALIZED;
if (!aPresShell) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsISelectionController> selcon;
selcon = do_QueryInterface(mPresShell);
selcon = do_QueryInterface(aPresShell);
if (selcon)
return selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, aSelection);
return NS_ERROR_FAILURE;
}
nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection)
{
if (!mPresShell) return NS_ERROR_NOT_INITIALIZED;
return GetDocumentSelection(mPresShell, aSelection);
}
NS_IMETHODIMP
DocumentViewerImpl::CreateDocumentViewerUsing(nsIPresContext* aPresContext,
nsIDocumentViewer*& aResult)
@ -1386,6 +1909,8 @@ void DocumentViewerImpl::DocumentReadyForPrinting()
NS_RELEASE(mPrintVM);
NS_RELEASE(mPrintSS);
NS_RELEASE(mPrintDC);
NS_IF_RELEASE(mSelectionDoc);
}
}
@ -1535,6 +2060,198 @@ DocumentViewerImpl::GetSaveable(PRBool *aSaveable)
static NS_DEFINE_IID(kDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTORY_CID);
//------------------------------------------------------------------
#include "nsINodeInfo.h"
#include "nsIDocument.h"
#include "nsHTMLAtoms.h"
#include "nsIHTMLContent.h"
#include "nsINameSpaceManager.h"
#include "nsIWebShell.h"
static NS_DEFINE_IID(kWebShellCID, NS_WEB_SHELL_CID);
static NS_DEFINE_IID(kCViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kCChildCID, NS_CHILD_CID);
#if 0
nsresult
DocumentViewerImpl::CreateDocShell(nsIPresContext* aPresContext, const nsSize& aSize)
{
nsresult rv;
mSelectionDocShell = do_CreateInstance(kWebShellCID);
NS_ENSURE_TRUE(mSelectionDocShell, NS_ERROR_FAILURE);
// pass along marginwidth and marginheight so sub document can use it
mSelectionDocShell->SetMarginWidth(0);
mSelectionDocShell->SetMarginHeight(0);
/* our parent must be a docshell. we need to get our prefs from our parent */
nsCOMPtr<nsISupports> container;
aPresContext->GetContainer(getter_AddRefs(container));
NS_ENSURE_TRUE(container, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsIDocShell> outerShell = do_QueryInterface(container);
NS_ENSURE_TRUE(outerShell, NS_ERROR_UNEXPECTED);
float t2p;
aPresContext->GetTwipsToPixels(&t2p);
nsCOMPtr<nsIPresShell> presShell;
rv = aPresContext->GetShell(getter_AddRefs(presShell));
if (NS_FAILED(rv)) { return rv; }
// create, init, set the parent of the view
nsIView* view;
rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, NS_GET_IID(nsIView),
(void **)&view);
if (NS_FAILED(rv)) { return rv; }
nsIView* parView;
nsPoint origin;
GetOffsetFromView(aPresContext, origin, &parView);
nsRect viewBounds(origin.x, origin.y, aSize.width, aSize.height);
#ifdef NOISY
printf("%p view bounds: x=%d, y=%d, w=%d, h=%d\n", view, origin.x, origin.y, aSize.width, aSize.height);
#endif
nsCOMPtr<nsIViewManager> viewMan;
presShell->GetViewManager(getter_AddRefs(viewMan));
rv = view->Init(viewMan, viewBounds, parView);
if (NS_FAILED(rv)) { return rv; }
viewMan->InsertChild(parView, view, 0);
rv = view->CreateWidget(kCChildCID);
if (NS_FAILED(rv)) { return rv; }
SetView(aPresContext, view);
// if the visibility is hidden, reflect that in the view
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
if (!display->IsVisible()) {
view->SetVisibility(nsViewVisibility_kHide);
}
const nsStyleSpacing* spacing;
GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
nsMargin border;
spacing->CalcBorderFor(this, border);
nsCOMPtr<nsIWidget> widget;
view->GetWidget(*getter_AddRefs(widget));
mSelectionDocShell->SetAllowPlugins(PR_FALSE);
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mSelectionDocShell));
PRInt32 x = NSToCoordRound(border.left * t2p);
PRInt32 y = NSToCoordRound(border.top * t2p);
PRInt32 cx = NSToCoordRound((aSize.width - border.right) * t2p);
PRInt32 cy = NSToCoordRound((aSize.height - border.bottom) * t2p);
NS_ENSURE_SUCCESS(docShellAsWin->InitWindow(nsnull, widget, (x >= 0) ? x : 0,
(y >= 0) ? y : 0, cx, cy), NS_ERROR_FAILURE);
NS_ENSURE_SUCCESS(docShellAsWin->Create(), NS_ERROR_FAILURE);
// move the view to the proper location
viewMan->MoveViewTo(view, origin.x, origin.y);
mSelectionDocShell->SetDocLoaderObserver(mTempObserver);
PRInt32 type;
GetType(&type);
if ((PR_FALSE==IsSingleLineTextControl()) || (NS_FORM_INPUT_PASSWORD == type)) {
docShellAsWin->SetVisibility(PR_TRUE);
}
return NS_OK;
}
#endif
//nsresult DocumentViewerImpl::PrintSelection(nsIDeviceContextSpec * aDevSpec)
nsresult DocumentViewerImpl::GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc)
{
//NS_ENSURE_ARG_POINTER(*aDevSpec);
NS_ENSURE_ARG_POINTER(aNewDoc);
// create document
nsCOMPtr<nsIDocument> doc;
nsresult rv = NS_NewHTMLDocument(getter_AddRefs(doc));
if (NS_FAILED(rv)) { return rv; }
if (!doc) { return NS_ERROR_NULL_POINTER; }
nsCOMPtr<nsINodeInfoManager> nimgr;
rv = doc->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsINodeInfo> nodeInfo;
nimgr->GetNodeInfo(nsHTMLAtoms::html, nsnull, kNameSpaceID_None,
*getter_AddRefs(nodeInfo));
// create document content
nsCOMPtr<nsIHTMLContent> htmlElement;
nsCOMPtr<nsIHTMLContent> headElement;
nsCOMPtr<nsIHTMLContent> bodyElement;
// create the root
rv = NS_NewHTMLHtmlElement(getter_AddRefs(htmlElement), nodeInfo);
if (NS_FAILED(rv)) { return rv; }
if (!htmlElement) { return NS_ERROR_NULL_POINTER; }
// create the head
nimgr->GetNodeInfo(NS_ConvertASCIItoUCS2("head"), nsnull,
kNameSpaceID_None, *getter_AddRefs(nodeInfo));
rv = NS_NewHTMLHeadElement(getter_AddRefs(headElement), nodeInfo);
if (NS_FAILED(rv)) { return rv; }
if (!headElement) { return NS_ERROR_NULL_POINTER; }
headElement->SetDocument(doc, PR_FALSE, PR_TRUE);
// create the body
nimgr->GetNodeInfo(nsHTMLAtoms::body, nsnull, kNameSpaceID_None,
*getter_AddRefs(nodeInfo));
rv = NS_NewHTMLBodyElement(getter_AddRefs(bodyElement), nodeInfo);
if (NS_FAILED(rv)) { return rv; }
if (!bodyElement) { return NS_ERROR_NULL_POINTER; }
bodyElement->SetDocument(doc, PR_FALSE, PR_TRUE);
// put the head and body into the root
rv = htmlElement->AppendChildTo(headElement, PR_FALSE);
if (NS_FAILED(rv)) { return rv; }
rv = htmlElement->AppendChildTo(bodyElement, PR_FALSE);
if (NS_FAILED(rv)) { return rv; }
// load the document into the docshell
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc);
if (!domDoc) { return NS_ERROR_NULL_POINTER; }
nsCOMPtr<nsIDOMElement> htmlDOMElement = do_QueryInterface(htmlElement);
if (!htmlDOMElement) { return NS_ERROR_NULL_POINTER; }
//nsCOMPtr<nsIContent> rootContent(do_QueryInterface(htmlElement));
//doc->SetRootContent(rootContent);
*aNewDoc = doc.get();
NS_ADDREF(*aNewDoc);
return rv;
}
PRBool
DocumentViewerImpl::IsThereASelection()
{
// check here to see if there is a range selection
// so we know whether to turn on the "Selection" radio button
nsCOMPtr<nsISelection> selection;
GetDocumentSelection(getter_AddRefs(selection));
if (selection) {
PRInt32 count;
selection->GetRangeCount(&count);
if (count == 1) {
nsCOMPtr<nsIDOMRange> range;
if (NS_SUCCEEDED(selection->GetRangeAt(0, getter_AddRefs(range)))) {
// check to make sure it isn't an insertion selection
PRBool isCollapsed;
selection->GetIsCollapsed(&isCollapsed);
return !isCollapsed;
}
}
}
return PR_FALSE;
}
/** ---------------------------------------------------
* See documentation above in the nsIContentViewerfile class definition
@ -1543,9 +2260,15 @@ static NS_DEFINE_IID(kDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTOR
NS_IMETHODIMP
DocumentViewerImpl::Print(PRBool aSilent,FILE *aFile, nsIPrintListener *aPrintListener)
{
nsCOMPtr<nsIWebShell> webContainer;
nsCOMPtr<nsIDeviceContextSpecFactory> factory;
PRInt32 width,height;
nsCOMPtr<nsIWebShell> webContainer;
nsCOMPtr<nsIDeviceContextSpecFactory> factory;
PRInt32 width,height;
nsresult rv = NS_ERROR_FAILURE;
NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv);
if (NS_SUCCEEDED(rv) && printService) {
printService->SetPrintOptions(NS_PRINT_OPTIONS_ENABLE_SELECTION_RADIO, IsThereASelection());
}
nsComponentManager::CreateInstance(kDeviceContextSpecFactoryCID,
nsnull,
@ -1566,11 +2289,14 @@ PRInt32 width,height;
factory->CreateDeviceContextSpec(nsnull, devspec, aSilent);
if (nsnull != devspec) {
mPresContext->GetDeviceContext(getter_AddRefs(dx));
nsresult rv = dx->GetDeviceContextFor(devspec, mPrintDC);
rv = dx->GetDeviceContextFor(devspec, mPrintDC);
if (NS_SUCCEEDED(rv)) {
NS_RELEASE(devspec);
nsCOMPtr<nsIDocument> printDoc;
printDoc = mDocument;
// Get the webshell for this documentviewer
webContainer = do_QueryInterface(mContainer);
if(webContainer) {
@ -1588,15 +2314,24 @@ PRInt32 width,height;
mPrintDC->GetDeviceSurfaceDimensions(width,height);
// XXX - Hack Alert
// OK, so ther eis a selection, we will print the entire selection
// on one page and then crop the page.
// This means you can never print any selection that is longer than one page
// put it keeps it from page breaking in the middle of your print of the selection
if (IsThereASelection()) {
height = 0x0FFFFFFF;
}
mPrintPC->Init(mPrintDC);
mPrintPC->SetContainer(webContainer);
CreateStyleSet(mDocument,&mPrintSS);
CreateStyleSet(printDoc,&mPrintSS);
rv = NS_NewPresShell(&mPrintPS);
if(NS_FAILED(rv)){
return rv;
}
rv = nsComponentManager::CreateInstance(kViewManagerCID, nsnull, NS_GET_IID(nsIViewManager),(void**)&mPrintVM);
if(NS_FAILED(rv)) {
return rv;
@ -1611,7 +2346,7 @@ PRInt32 width,height;
if(NS_FAILED(rv)) {
return rv;
}
nsRect tbounds = nsRect(0,0,width,height);
rv = mPrintView->Init(mPrintVM,tbounds,nsnull);
if(NS_FAILED(rv)) {
@ -1620,7 +2355,7 @@ PRInt32 width,height;
// setup hierarchical relationship in view manager
mPrintVM->SetRootView(mPrintView);
mPrintPS->Init(mDocument,mPrintPC,mPrintVM,mPrintSS);
mPrintPS->Init(printDoc,mPrintPC,mPrintVM,mPrintSS);
nsCOMPtr<nsIImageGroup> imageGroup;
mPrintPC->GetImageGroup(getter_AddRefs(imageGroup));

View File

@ -23,6 +23,44 @@
#include "nsISupports.idl"
%{ C++
#include "nsMargin.h"
#include "nsFont.h"
enum nsPrintRange {
ePrintRange_AllPages, // print all pages
ePrintRange_SpecifiedPageRange, // only print pages in the specified range
ePrintRange_Selection, // only print the selection
ePrintRange_FocusFrame // only print the frame with the current focus
};
/**
* Print Option Printing state bits.
*/
typedef PRUint32 nsPrintOptionsType;
#define NS_PRINT_OPTIONS_PRINT_ODD_PAGES 0x00000001
#define NS_PRINT_OPTIONS_PRINT_EVEN_PAGES 0x00000002
#define NS_PRINT_OPTIONS_PRINT_DOC_TITLE 0x00000004
#define NS_PRINT_OPTIONS_PRINT_DOC_LOCATION 0x00000008
#define NS_PRINT_OPTIONS_PRINT_PAGE_NUMS 0x00000010
#define NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL 0x00000020
#define NS_PRINT_OPTIONS_PRINT_DATE_PRINTED 0x00000040
#define NS_PRINT_OPTIONS_ENABLE_SELECTION_RADIO 0x00000080
// There are currently NOT supported
#define NS_PRINT_OPTIONS_PRINT_BEVEL_LINES 0x00000100
#define NS_PRINT_OPTIONS_PRINT_BLACK_TEXT 0x00000200
#define NS_PRINT_OPTIONS_PRINT_BLACK_LINES 0x00000400
#define NS_PRINT_OPTIONS_PRINT_LAST_PAGE_FIRST 0x00000800
#define NS_PRINT_OPTIONS_PRINT_BACKGROUNDS 0x00001000
// Justification Flags
#define NS_PRINT_JUSTIFY_LEFT 0x00000001
#define NS_PRINT_JUSTIFY_CENTER 0x00000002
#define NS_PRINT_JUSTIFY_RIGHT 0x00000004
%}
/**
* Simplified graphics interface for JS rendering.
@ -32,14 +70,107 @@
interface nsIPrintOptions : nsISupports
{
%{C++
// Set Default Font of Header and footer
NS_IMETHOD SetDefaultFont(const nsFont &aFont) = 0;
NS_IMETHOD SetFontNamePointSize(const nsString& aFontName, nscoord aPointSize) = 0;
NS_IMETHOD GetDefaultFont(nsFont &aFont) = 0;
// non-scriptable helper method
NS_IMETHOD GetMargin(nsMargin& aMargin) = 0;
%}
/**
* PageMargin.
* Set PageMargins
*/
void SetMargins(in PRInt32 aTop, in PRInt32 aLeft, in PRInt32 aRight, in PRInt32 aBottom);
/**
* Get PageMargins
*/
void GetMargins(out PRInt32 aTop, out PRInt32 aLeft, out PRInt32 aRight, out PRInt32 aBottom);
/**
* Show Native Print Options dialog, this may not be supported on all platforms
*/
void ShowNativeDialog();
/**
* Set Print Range
*/
void SetPrintRange(in PRInt32 aPrintRange);
/**
* Get Print Range
*/
void GetPrintRange(out PRInt32 aPrintRange);
/**
* Set Page Range
*/
void SetPageRange(in PRInt32 aStartPage, in PRInt32 aEndPage);
/**
* Get Page Range
*/
void GetPageRange(out PRInt32 aStartPage, out PRInt32 aEndPage);
/**
* Set PrintOptions
*/
void SetPrintOptions(in PRInt32 aType, in PRBool aTurnOnOff);
/**
* Get PrintOptions
*/
void GetPrintOptions(in PRInt32 aType, out PRBool aTurnOnOff);
/**
* Set PrintOptions Bit field
*/
void GetPrintOptionsBits(out PRInt32 aBits);
/**
* Set Title field for Header
*/
void SetTitle(in wstring aTitle);
/**
* Get Title field for Header
*/
void GetTitle(out wstring aTitle);
/**
* Set URL field for Header
*/
void SetURL(in wstring aURL);
/**
* Get URL field for Header
*/
void GetURL(out wstring aURL);
/**
* Set Page Number Print Justification
*/
void SetPageNumJust(in PRInt32 aJust);
/**
* Set Page Number Print Justification
*/
void GetPageNumJust(out PRInt32 aJust);
/**
* Read Prefs
*/
void ReadPrefs();
/**
* Write Prefs
*/
void WritePrefs();
};

View File

@ -24,6 +24,8 @@
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsIPrintOptions.h"
#include "nsGfxCIID.h"
#include "nsIPref.h"
#include "prenv.h" /* for PR_GetEnv */
@ -36,6 +38,7 @@
static NS_DEFINE_IID( kAppShellServiceCID, NS_APPSHELL_SERVICE_CID );
static NS_DEFINE_CID(kDialogParamBlockCID, NS_DialogParamBlock_CID);
static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID);
//#include "prmem.h"
//#include "plstr.h"
@ -124,16 +127,30 @@ NS_IMPL_RELEASE(nsDeviceContextSpecGTK)
*/
NS_IMETHODIMP nsDeviceContextSpecGTK :: Init(PRBool aQuiet)
{
nsresult rv = NS_ERROR_FAILURE;
NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv);
// if there is a current selection then enable the "Selection" radio button
if (NS_SUCCEEDED(rv) && printService) {
PRBool isOn;
printService->GetPrintOptions(NS_PRINT_OPTIONS_ENABLE_SELECTION_RADIO, &isOn);
nsCOMPtr<nsIPref> pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv) && pPrefs) {
(void) pPrefs->SetBoolPref("print.selection_radio_enabled", isOn);
}
}
char *path;
PRBool reversed = PR_FALSE, color = PR_FALSE, landscape = PR_FALSE;
PRBool tofile = PR_FALSE;
PRBool tofile = PR_FALSE, allpagesRange = PR_TRUE, pageRange = PR_FALSE, selectionRange = PR_FALSE;
PRInt32 paper_size = NS_LETTER_SIZE;
int ileft = 500, iright = 0, itop = 500, ibottom = 0;
PRInt32 fromPage = 1, toPage = 1;
int ileft = 500, iright = 500, itop = 500, ibottom = 500;
char *command;
char *printfile = nsnull;
nsresult rv = NS_OK;
rv = NS_OK;
nsCOMPtr<nsIDialogParamBlock> ioParamBlock;
rv = nsComponentManager::CreateInstance(kDialogParamBlockCID,
@ -179,14 +196,58 @@ NS_IMETHODIMP nsDeviceContextSpecGTK :: Init(PRBool aQuiet)
(void) pPrefs->GetBoolPref("print.print_landscape", &landscape);
(void) pPrefs->GetIntPref("print.print_paper_size", &paper_size);
(void) pPrefs->CopyCharPref("print.print_command", (char **) &command);
(void) pPrefs->GetIntPref("print.print_margin_top", &itop);
(void) pPrefs->GetIntPref("print.print_margin_left", &ileft);
(void) pPrefs->GetIntPref("print.print_margin_bottom", &ibottom);
(void) pPrefs->GetIntPref("print.print_margin_right", &iright);
// the _js extention means these were set via script with the xp
// dialog as integers, int * 1000, meaning a 0.5 inches is 500
// the "real" values are set into the prefs as strings
// the PrintOption object will save out these values as twips
// in the prefs with these names without the _js extention
(void) pPrefs->GetIntPref("print.print_margin_top_js", &itop);
(void) pPrefs->GetIntPref("print.print_margin_left_js", &ileft);
(void) pPrefs->GetIntPref("print.print_margin_bottom_js", &ibottom);
(void) pPrefs->GetIntPref("print.print_margin_right_js", &iright);
(void) pPrefs->CopyCharPref("print.print_file", (char **) &printfile);
(void) pPrefs->GetBoolPref("print.print_tofile", &tofile);
(void) pPrefs->GetBoolPref("print.print_allpagesrange", &allpagesRange);
(void) pPrefs->GetBoolPref("print.print_pagerange", &pageRange);
(void) pPrefs->GetBoolPref("print.print_selectionrange", &selectionRange);
(void) pPrefs->GetIntPref("print.print_frompage", &fromPage);
(void) pPrefs->GetIntPref("print.print_topage", &toPage);
sprintf( mPrData.command, command );
sprintf( mPrData.path, printfile );
// fill the print options with the info from the dialog
if(printService) {
// convert the script values to twips
nsMargin margin;
margin.SizeTo(NS_INCHES_TO_TWIPS(float(ileft)/1000.0),
NS_INCHES_TO_TWIPS(float(itop)/1000.0),
NS_INCHES_TO_TWIPS(float(iright)/1000.0),
NS_INCHES_TO_TWIPS(float(ibottom)/1000.0));
printService->SetMargins(margin.top, margin.left, margin.right, margin.bottom);
#ifdef DEBUG_rods
printf("margins: %d,%d,%d,%d\n", itop, ileft, ibottom, iright);
printf("margins: %d,%d,%d,%d (twips)\n", margin.top, margin.left, margin.bottom, margin.right);
printf("allpagesRange %d\n", allpagesRange);
printf("pageRange %d\n", pageRange);
printf("selectionRange %d\n", selectionRange);
printf("fromPage %d\n", fromPage);
printf("toPage %d\n", toPage);
#endif
if (selectionRange) {
printService->SetPrintRange(ePrintRange_Selection);
} else if (pageRange) {
printService->SetPrintRange(ePrintRange_SpecifiedPageRange);
printService->SetPageRange(fromPage, toPage);
} else { // (allpagesRange)
printService->SetPrintRange(ePrintRange_AllPages);
}
}
} else {
#ifndef VMS
sprintf( mPrData.command, "lpr" );

View File

@ -21,18 +21,72 @@
*/
#include "nsPrintOptionsImpl.h"
#include "nsCoord.h"
#include "nsUnitConversion.h"
// For Prefs
#include "nsIPref.h"
#include "nsIServiceManager.h"
NS_IMPL_ISUPPORTS1(nsPrintOptions, nsIPrintOptions)
// Pref Constants
const char * kMarginTop = "print.print_margin_top";
const char * kMarginLeft = "print.print_margin_left";
const char * kMarginBottom = "print.print_margin_bottom";
const char * kMarginRight = "print.print_margin_right";
// Prefs for Print Option
const char * kPrintEvenPages = "print.print_evenpages";
const char * kPrintOddPages = "print.print_oddpages";
const char * kPrintDocTitle = "print.print_doctitle";
const char * kPrintDocLoc = "print.print_doclocation";
const char * kPageNums = "print.print_pagenumbers";
const char * kPageNumsJust = "print.print_pagenumjust";
const char * kPrintPageTotals = "print.print_pagetotals";
const char * kPrintDate = "print.print_date";
// There are currently NOT supported
//const char * kPrintBevelLines = "print.print_bevellines";
//const char * kPrintBlackText = "print.print_blacktext";
//const char * kPrintBlackLines = "print.print_blacklines";
//const char * kPrintLastPageFirst = "print.print_lastpagefirst";
//const char * kPrintBackgrounds = "print.print_backgrounds";
const char * kLeftJust = "left";
const char * kCenterJust = "center";
const char * kRightJust = "right";
#define form_properties "chrome://communicator/locale/printing.properties"
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 6/21/00 dwc
*/
nsPrintOptions::nsPrintOptions()
nsPrintOptions::nsPrintOptions() :
mPrintRange(ePrintRange_AllPages),
mStartPageNum(0),
mEndPageNum(0),
mPrintOptions(0L)
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
nscoord halfInch = NS_INCHES_TO_TWIPS(0.5);
SetMargins(halfInch, halfInch, halfInch, halfInch);
mPrintOptions = NS_PRINT_OPTIONS_PRINT_EVEN_PAGES |
NS_PRINT_OPTIONS_PRINT_ODD_PAGES |
NS_PRINT_OPTIONS_PRINT_DOC_LOCATION |
NS_PRINT_OPTIONS_PRINT_DOC_TITLE |
NS_PRINT_OPTIONS_PRINT_PAGE_NUMS |
NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL |
NS_PRINT_OPTIONS_PRINT_DATE_PRINTED;
mDefaultFont = new nsFont("Times", NS_FONT_STYLE_NORMAL,NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL,0,NSIntPointsToTwips(10));
ReadPrefs();
}
/** ---------------------------------------------------
@ -41,20 +95,79 @@ nsPrintOptions::nsPrintOptions()
*/
nsPrintOptions::~nsPrintOptions()
{
/* destructor code */
if (mDefaultFont != nsnull) {
delete mDefaultFont;
}
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::SetDefaultFont(const nsFont &aFont)
{
if (mDefaultFont != nsnull) {
delete mDefaultFont;
}
mDefaultFont = new nsFont(aFont);
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::SetFontNamePointSize(const nsString& aFontName, nscoord aPointSize)
{
if (mDefaultFont != nsnull && aFontName.Length() > 0 && aPointSize > 0) {
mDefaultFont->name = aFontName;
mDefaultFont->size = NSIntPointsToTwips(aPointSize);
}
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::GetDefaultFont(nsFont &aFont)
{
aFont = *mDefaultFont;
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 6/21/00 dwc
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::SetMargins(PRInt32 aTop, PRInt32 aLeft, PRInt32 aRight, PRInt32 aBottom)
{
mTopMargin = aTop;
mLeftMargin = aLeft;
mRightMargin = aRight;
mBottomMargin = aBottom;
mMargin.SizeTo(aLeft, aTop, aRight, aBottom);
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 6/21/00 dwc
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::GetMargins(PRInt32 *aTop, PRInt32 *aLeft, PRInt32 *aRight, PRInt32 *aBottom)
{
NS_ENSURE_ARG_POINTER(aTop);
NS_ENSURE_ARG_POINTER(aLeft);
NS_ENSURE_ARG_POINTER(aRight);
NS_ENSURE_ARG_POINTER(aBottom);
*aTop = mMargin.top;
*aLeft = mMargin.left;
*aRight = mMargin.right;
*aBottom = mMargin.bottom;
return NS_OK;
}
@ -64,13 +177,10 @@ nsPrintOptions::SetMargins(PRInt32 aTop, PRInt32 aLeft, PRInt32 aRight, PRInt32
* @update 6/21/00 dwc
*/
NS_IMETHODIMP
nsPrintOptions::GetMargins(PRInt32 *aTop, PRInt32 *aLeft, PRInt32 *aRight, PRInt32 *aBottom)
nsPrintOptions::GetMargin(nsMargin& aMargin)
{
*aTop = mTopMargin;
*aLeft = mLeftMargin;
*aRight = mRightMargin;
*aBottom = mBottomMargin;
aMargin = mMargin;
//aMargin.SizeTo(mLeftMargin, mTopMargin, mRightMargin, mBottomMargin);
return NS_OK;
}
@ -84,3 +194,329 @@ nsPrintOptions::ShowNativeDialog()
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::SetPrintRange(PRInt32 aPrintRange)
{
mPrintRange = (nsPrintRange)aPrintRange;
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::GetPrintRange(PRInt32 *aPrintRange)
{
NS_ENSURE_ARG_POINTER(aPrintRange);
*aPrintRange = (PRInt32)mPrintRange;
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::SetPageRange(PRInt32 aStartPage, PRInt32 aEndPage)
{
mStartPageNum = aStartPage;
mEndPageNum = aEndPage;
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::GetPageRange(PRInt32 *aStartPage, PRInt32 *aEndPage)
{
NS_ENSURE_ARG_POINTER(aStartPage);
NS_ENSURE_ARG_POINTER(aEndPage);
*aStartPage = mStartPageNum;
*aEndPage = mEndPageNum;
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::SetPrintOptions(PRInt32 aType, PRBool aTurnOnOff)
{
if (aTurnOnOff) {
mPrintOptions |= aType;
} else {
mPrintOptions &= ~aType;
}
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::GetPrintOptions(PRInt32 aType, PRBool *aTurnOnOff)
{
NS_ENSURE_ARG_POINTER(aTurnOnOff);
*aTurnOnOff = mPrintOptions & aType;
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::GetPrintOptionsBits(PRInt32 *aBits)
{
NS_ENSURE_ARG_POINTER(aBits);
*aBits = mPrintOptions;
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::SetTitle(const PRUnichar *aTitle)
{
NS_ENSURE_ARG_POINTER(aTitle);
mTitle = aTitle;
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::GetTitle(PRUnichar **aTitle)
{
NS_ENSURE_ARG_POINTER(aTitle);
*aTitle = mTitle.ToNewUnicode();
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::SetURL(const PRUnichar *aURL)
{
NS_ENSURE_ARG_POINTER(aURL);
mURL = aURL;
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::GetURL(PRUnichar **aURL)
{
NS_ENSURE_ARG_POINTER(aURL);
*aURL = mURL.ToNewUnicode();
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::SetPageNumJust(PRInt32 aJust)
{
mPageNumJust = aJust;
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::GetPageNumJust(PRInt32 *aJust)
{
NS_ENSURE_ARG_POINTER(aJust);
*aJust = (PRInt32)mPageNumJust;
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::ReadPrefs()
{
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID);
if (prefs) {
ReadInchesToTwipsPref(prefs, kMarginTop, mMargin.top);
ReadInchesToTwipsPref(prefs, kMarginLeft, mMargin.left);
ReadInchesToTwipsPref(prefs, kMarginBottom, mMargin.bottom);
ReadInchesToTwipsPref(prefs, kMarginRight, mMargin.right);
ReadBitFieldPref(prefs, kPrintEvenPages, NS_PRINT_OPTIONS_PRINT_EVEN_PAGES);
ReadBitFieldPref(prefs, kPrintOddPages, NS_PRINT_OPTIONS_PRINT_ODD_PAGES);
ReadBitFieldPref(prefs, kPrintDocTitle, NS_PRINT_OPTIONS_PRINT_DOC_TITLE);
ReadBitFieldPref(prefs, kPrintDocLoc, NS_PRINT_OPTIONS_PRINT_DOC_LOCATION);
ReadBitFieldPref(prefs, kPageNums, NS_PRINT_OPTIONS_PRINT_PAGE_NUMS);
ReadBitFieldPref(prefs, kPrintPageTotals, NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL);
ReadBitFieldPref(prefs, kPrintDate, NS_PRINT_OPTIONS_PRINT_DATE_PRINTED);
ReadJustification(prefs, kPageNumsJust, mPageNumJust, NS_PRINT_JUSTIFY_LEFT);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
/** ---------------------------------------------------
* See documentation in nsPrintOptionsImpl.h
* @update 1/12/01 rods
*/
NS_IMETHODIMP
nsPrintOptions::WritePrefs()
{
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID);
if (prefs) {
WriteInchesFromTwipsPref(prefs, kMarginTop, mMargin.top);
WriteInchesFromTwipsPref(prefs, kMarginLeft, mMargin.left);
WriteInchesFromTwipsPref(prefs, kMarginBottom, mMargin.bottom);
WriteInchesFromTwipsPref(prefs, kMarginRight, mMargin.right);
WriteBitFieldPref(prefs, kPrintEvenPages, NS_PRINT_OPTIONS_PRINT_EVEN_PAGES);
WriteBitFieldPref(prefs, kPrintOddPages, NS_PRINT_OPTIONS_PRINT_ODD_PAGES);
WriteBitFieldPref(prefs, kPrintDocTitle, NS_PRINT_OPTIONS_PRINT_DOC_TITLE);
WriteBitFieldPref(prefs, kPrintDocLoc, NS_PRINT_OPTIONS_PRINT_DOC_LOCATION);
WriteBitFieldPref(prefs, kPageNums, NS_PRINT_OPTIONS_PRINT_PAGE_NUMS);
WriteBitFieldPref(prefs, kPrintPageTotals, NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL);
WriteBitFieldPref(prefs, kPrintDate, NS_PRINT_OPTIONS_PRINT_DATE_PRINTED);
WriteJustification(prefs, kPageNumsJust, mPageNumJust);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
//-----------------------------------------------------
//-- Protected Methods
//-----------------------------------------------------
void nsPrintOptions::ReadBitFieldPref(nsIPref * aPref,
const char * aPrefId,
PRInt32 anOption)
{
PRBool b;
if (NS_SUCCEEDED(aPref->GetBoolPref(aPrefId, &b))) {
SetPrintOptions(anOption, b);
}
}
//---------------------------------------------------
void nsPrintOptions::WriteBitFieldPref(nsIPref * aPref,
const char * aPrefId,
PRInt32 anOption)
{
PRBool b;
GetPrintOptions(anOption, &b);
aPref->SetBoolPref(aPrefId, b);
}
//---------------------------------------------------
void nsPrintOptions::ReadInchesToTwipsPref(nsIPref * aPref,
const char * aPrefId,
nscoord& aTwips)
{
char * str = nsnull;
nsresult rv = aPref->CopyCharPref(aPrefId, &str);
if (NS_SUCCEEDED(rv) && str) {
nsAutoString justStr;
justStr.AssignWithConversion(str);
PRInt32 errCode;
float inches = justStr.ToFloat(&errCode);
if (NS_SUCCEEDED(errCode)) {
aTwips = NS_INCHES_TO_TWIPS(inches);
} else {
aTwips = 0;
}
nsMemory::Free(str);
}
}
//---------------------------------------------------
void nsPrintOptions::WriteInchesFromTwipsPref(nsIPref * aPref,
const char * aPrefId,
nscoord aTwips)
{
double inches = NS_TWIPS_TO_INCHES(aTwips);
nsAutoString inchesStr;
inchesStr.AppendFloat(inches);
char * str = inchesStr.ToNewCString();
if (str) {
aPref->SetCharPref(aPrefId, str);
} else {
aPref->SetCharPref(aPrefId, "0.5");
}
}
//---------------------------------------------------
void nsPrintOptions::ReadJustification(nsIPref * aPref,
const char * aPrefId,
PRInt32& aJust,
PRInt32 aInitValue)
{
aJust = aInitValue;
char * str = nsnull;
nsresult rv = aPref->CopyCharPref(aPrefId, &str);
if (NS_SUCCEEDED(rv) && str) {
nsAutoString justStr;
justStr.AssignWithConversion(str);
if (justStr.EqualsWithConversion(kRightJust)) {
aJust = NS_PRINT_JUSTIFY_RIGHT;
} else if (justStr.EqualsWithConversion(kCenterJust)) {
aJust = NS_PRINT_JUSTIFY_CENTER;
} else {
aJust = NS_PRINT_JUSTIFY_LEFT;
}
nsMemory::Free(str);
}
}
//---------------------------------------------------
void nsPrintOptions::WriteJustification(nsIPref * aPref,
const char * aPrefId,
PRInt32 aJust)
{
switch (aJust) {
case NS_PRINT_JUSTIFY_LEFT:
aPref->SetCharPref(aPrefId, kLeftJust);
break;
case NS_PRINT_JUSTIFY_CENTER:
aPref->SetCharPref(aPrefId, kCenterJust);
break;
case NS_PRINT_JUSTIFY_RIGHT:
aPref->SetCharPref(aPrefId, kRightJust);
break;
} //switch
}

View File

@ -25,6 +25,7 @@
#include "nsIPrintOptions.h"
class nsIPref;
//*****************************************************************************
//*** nsPrintOptions
@ -35,17 +36,39 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPRINTOPTIONS
// C++ methods
NS_IMETHOD SetDefaultFont(const nsFont &aFont);
NS_IMETHOD SetFontNamePointSize(const nsString& aFontName, nscoord aPointSize);
NS_IMETHOD GetDefaultFont(nsFont &aFont);
// non-scriptable C++ helper method
NS_IMETHOD GetMargin(nsMargin& aMargin);
nsPrintOptions();
virtual ~nsPrintOptions();
protected:
void ReadBitFieldPref(nsIPref * aPref, const char * aPrefId, PRInt32 anOption);
void WriteBitFieldPref(nsIPref * aPref, const char * aPrefId, PRInt32 anOption);
void ReadJustification(nsIPref * aPref, const char * aPrefId, PRInt32& aJust, PRInt32 aInitValue);
void WriteJustification(nsIPref * aPref, const char * aPrefId, PRInt32 aJust);
void ReadInchesToTwipsPref(nsIPref * aPref, const char * aPrefId, nscoord& aTwips);
void WriteInchesFromTwipsPref(nsIPref * aPref, const char * aPrefId, nscoord aTwips);
// Members
PRInt32 mTopMargin;
PRInt32 mLeftMargin;
PRInt32 mRightMargin;
PRInt32 mBottomMargin;
nsMargin mMargin;
nsPrintRange mPrintRange;
PRInt32 mStartPageNum; // only used for ePrintRange_SpecifiedRange
PRInt32 mEndPageNum;
PRInt32 mPageNumJust;
PRInt32 mPrintOptions;
nsFont* mDefaultFont;
nsString mTitle;
nsString mURL;
};

View File

@ -26,6 +26,9 @@
#include <commdlg.h>
#include "nsGfxCIID.h"
#include "plstr.h"
#include "nsIServiceManager.h"
#include "nsIPrintOptions.h"
nsDeviceContextSpecFactoryWin :: nsDeviceContextSpecFactoryWin()
{
@ -38,6 +41,7 @@ nsDeviceContextSpecFactoryWin :: ~nsDeviceContextSpecFactoryWin()
static NS_DEFINE_IID(kIDeviceContextSpecIID, NS_IDEVICE_CONTEXT_SPEC_IID);
static NS_DEFINE_IID(kDeviceContextSpecCID, NS_DEVICE_CONTEXT_SPEC_CID);
static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID);
NS_IMPL_ISUPPORTS1(nsDeviceContextSpecFactoryWin, nsIDeviceContextSpecFactory)
@ -52,19 +56,30 @@ NS_IMETHODIMP nsDeviceContextSpecFactoryWin :: CreateDeviceContextSpec(nsIDevice
nsIDeviceContextSpec *&aNewSpec,
PRBool aQuiet)
{
PRINTDLG prntdlg;
nsresult rv = NS_ERROR_FAILURE;
NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv);
PRINTDLG prntdlg;
prntdlg.lStructSize = sizeof(prntdlg);
prntdlg.hwndOwner = NULL; //XXX need to find a window here. MMP
prntdlg.hDevMode = NULL;
prntdlg.hDevNames = NULL;
prntdlg.hDC = NULL;
prntdlg.Flags = PD_ALLPAGES | PD_RETURNIC | PD_NOSELECTION | PD_HIDEPRINTTOFILE;
prntdlg.nFromPage = 0;
prntdlg.nToPage = 0;
prntdlg.Flags = PD_ALLPAGES | PD_RETURNIC | PD_HIDEPRINTTOFILE;
// if there is a current selection then enable the "Selection" radio button
if (printService) {
PRBool isOn;
printService->GetPrintOptions(NS_PRINT_OPTIONS_ENABLE_SELECTION_RADIO, &isOn);
if (!isOn) {
prntdlg.Flags |= PD_NOSELECTION;
}
}
prntdlg.nFromPage = 1;
prntdlg.nToPage = 1;
prntdlg.nMinPage = 0;
prntdlg.nMaxPage = 0;
prntdlg.nMaxPage = 1000;
prntdlg.nCopies = 1;
prntdlg.hInstance = NULL;
prntdlg.lCustData = 0;
@ -80,8 +95,6 @@ NS_IMETHODIMP nsDeviceContextSpecFactoryWin :: CreateDeviceContextSpec(nsIDevice
prntdlg.Flags = PD_RETURNDEFAULT;
}
BOOL res = ::PrintDlg(&prntdlg);
if (TRUE == res)
@ -95,10 +108,48 @@ NS_IMETHODIMP nsDeviceContextSpecFactoryWin :: CreateDeviceContextSpec(nsIDevice
PL_strcpy(device, &(((char *)devnames)[devnames->wDeviceOffset]));
PL_strcpy(driver, &(((char *)devnames)[devnames->wDriverOffset]));
#ifdef NS_DEBUG
printf("printer: driver %s, device %s\n", driver, device);
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
printf("printer: driver %s, device %s flags: %d\n", driver, device, prntdlg.Flags);
#endif
// fill the print options with the info from the dialog
if(printService) {
if (prntdlg.Flags & PD_SELECTION) {
printService->SetPrintRange(ePrintRange_Selection);
} else if (prntdlg.Flags & PD_PAGENUMS) {
printService->SetPrintRange(ePrintRange_SpecifiedPageRange);
printService->SetPageRange(prntdlg.nFromPage, prntdlg.nToPage);
} else { // (prntdlg.Flags & PD_ALLPAGES)
printService->SetPrintRange(ePrintRange_AllPages);
}
}
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
PRBool printSelection = prntdlg.Flags & PD_SELECTION;
PRBool printAllPages = prntdlg.Flags & PD_ALLPAGES;
PRBool printNumPages = prntdlg.Flags & PD_PAGENUMS;
PRInt32 fromPageNum = 0;
PRInt32 toPageNum = 0;
if (printNumPages) {
fromPageNum = prntdlg.nFromPage;
toPageNum = prntdlg.nToPage;
}
if (printSelection) {
printf("Printing the selection\n");
} else if (printAllPages) {
printf("Printing all the pages\n");
} else {
printf("Printing from page no. %d to %d\n", fromPageNum, toPageNum);
}
#endif
nsIDeviceContextSpec *devspec = nsnull;
nsComponentManager::CreateInstance(kDeviceContextSpecCID, nsnull, kIDeviceContextSpecIID, (void **)&devspec);

View File

@ -10097,7 +10097,8 @@ GetAlternateTextFor(nsIContent* aContent,
// If there's no "value" attribute either, then use the localized string
// for "Submit" as the alternate text.
if (NS_CONTENT_ATTR_NOT_THERE == rv) {
nsFormControlHelper::GetLocalizedString("Submit", aAltText);
nsFormControlHelper::GetLocalizedString(nsFormControlHelper::GetHTMLPropertiesFileName(),
"Submit", aAltText);
}
}
}

View File

@ -87,6 +87,13 @@
#include "nsIEventQueueService.h"
#include "nsIEventQueue.h"
// Print Options
#include "nsIPrintOptions.h"
#include "nsGfxCIID.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID);
#include "nsHTMLAtoms.h" // XXX until atoms get factored into nsLayoutAtoms
//focus
#include "nsIDOMEventReceiver.h"
#include "nsIDOMFocusListener.h"
@ -248,12 +255,16 @@ private:
const nsRect& aBounds);
nsresult GetDocumentSelection(nsISelection **aSelection);
nsresult GetDocumentSelection(nsIPresShell * aPresShell, nsISelection **aSelection);
nsresult FindFrameSetWithIID(nsIContent * aParentContent, const nsIID& aIID);
PRBool IsThereASelection();
//
// The following three methods are used for printing...
//
void DocumentReadyForPrinting();
//nsresult PrintSelection(nsIDeviceContextSpec * aDevSpec);
nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc);
static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent);
static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent);
@ -297,6 +308,8 @@ protected:
nsIViewManager *mPrintVM;
nsIView *mPrintView;
FILE *mFilePointer; // a file where information can go to when printing
nsIDocument *mSelectionDoc;
nsIDocShell *mSelectionDocShell;
nsCOMPtr<nsIPrintListener> mPrintListener; // An observer for printing...
@ -339,6 +352,7 @@ DocumentViewerImpl::DocumentViewerImpl()
mEnableRendering = PR_TRUE;
mFilePointer = nsnull;
mPrintListener = nsnull;
mSelectionDoc = nsnull;
}
DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext)
@ -879,6 +893,386 @@ DocumentViewerImpl::FindFrameSetWithIID(nsIContent * aParentContent, const nsIID
return NS_ERROR_FAILURE;
}
//---------------------------------------------------------------
//---------------------------------------------------------------
//-- Debug helper routines
//---------------------------------------------------------------
//---------------------------------------------------------------
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
/** ---------------------------------------------------
* Dumps Frames for Printing
*/
static void DumpFrames(FILE* out,
nsIPresContext* aPresContext,
nsIRenderingContext * aRendContext,
nsIFrame * aFrame,
PRInt32 aLevel)
{
nsIFrame * child;
aFrame->FirstChild(aPresContext, nsnull, &child);
while (child != nsnull) {
for (PRInt32 i=0;i<aLevel;i++) {
fprintf(out, " ");
}
nsAutoString tmp;
nsIFrameDebug* frameDebug;
if (NS_SUCCEEDED(child->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) {
frameDebug->GetFrameName(tmp);
}
fputs(tmp, out);
nsFrameState state;
child->GetFrameState(&state);
PRBool isSelected;
if (NS_SUCCEEDED(child->IsVisibleForPainting(aPresContext, *aRendContext, PR_TRUE, &isSelected))) {
fprintf(out, " %p %s", child, isSelected?"VIS":"UVS");
nsRect rect;
child->GetRect(rect);
fprintf(out, "[%d,%d,%d,%d] ", rect.x, rect.y, rect.width, rect.height);
nsIView * view;
child->GetView(aPresContext, &view);
fprintf(out, "v: %p ", view);
fprintf(out, "\n");
DumpFrames(out, aPresContext, aRendContext, child, aLevel+1);
child->GetNextSibling(&child);
}
}
}
/** ---------------------------------------------------
* Helper function needed for "DumpViews"
*/
static nsIPresShell*
GetPresShellFor(nsIDocShell* aDocShell)
{
nsIPresShell* shell = nsnull;
if (nsnull != aDocShell) {
nsIContentViewer* cv = nsnull;
aDocShell->GetContentViewer(&cv);
if (nsnull != cv) {
nsIDocumentViewer* docv = nsnull;
cv->QueryInterface(NS_GET_IID(nsIDocumentViewer), (void**) &docv);
if (nsnull != docv) {
nsIPresContext* cx;
docv->GetPresContext(cx);
if (nsnull != cx) {
cx->GetShell(&shell);
NS_RELEASE(cx);
}
NS_RELEASE(docv);
}
NS_RELEASE(cv);
}
}
return shell;
}
/** ---------------------------------------------------
* Dumps the Views from the DocShell
*/
static void
DumpViews(nsIDocShell* aDocShell, FILE* out)
{
if (nsnull != aDocShell) {
fprintf(out, "docshell=%p \n", aDocShell);
nsIPresShell* shell = GetPresShellFor(aDocShell);
if (nsnull != shell) {
nsCOMPtr<nsIViewManager> vm;
shell->GetViewManager(getter_AddRefs(vm));
if (vm) {
nsIView* root;
vm->GetRootView(root);
if (nsnull != root) {
root->List(out);
}
}
NS_RELEASE(shell);
}
else {
fputs("null pres shell\n", out);
}
// dump the views of the sub documents
PRInt32 i, n;
nsCOMPtr<nsIDocShellTreeNode> docShellAsNode(do_QueryInterface(aDocShell));
docShellAsNode->GetChildCount(&n);
for (i = 0; i < n; i++) {
nsCOMPtr<nsIDocShellTreeItem> child;
docShellAsNode->GetChildAt(i, getter_AddRefs(child));
nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
if (childAsShell) {
DumpViews(childAsShell, out);
}
}
}
}
/** ---------------------------------------------------
* Dumps the Views and Frames
*/
void DumpLayoutData(nsIPresContext* aPresContext,
nsIDeviceContext * aDC,
nsIFrame * aRootFrame,
nsIWebShell * aWebShell)
{
// Dump all the frames and view to a a file
FILE * fd = fopen("dump.txt", "w");
if (fd) {
fprintf(fd, "--------------- Frames ----------------\n");
nsCOMPtr<nsIRenderingContext> renderingContext;
aDC->CreateRenderingContext(*getter_AddRefs(renderingContext));
DumpFrames(fd, aPresContext, renderingContext, aRootFrame, 0);
fprintf(fd, "---------------------------------------\n\n");
fprintf(fd, "--------------- Views From Root Frame----------------\n");
nsIView * v;
aRootFrame->GetView(aPresContext, &v);
if (v) {
v->List(fd);
} else {
printf("View is null!\n");
}
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aWebShell));
if (docShell) {
fprintf(fd, "--------------- All Views ----------------\n");
DumpViews(docShell, fd);
fprintf(fd, "---------------------------------------\n\n");
}
fclose(fd);
}
}
#endif
//---------------------------------------------------------------
//---------------------------------------------------------------
//-- End of debug helper routines
//---------------------------------------------------------------
//---------------------------------------------------------------
/** ---------------------------------------------------
* Giving a child frame it searches "up" the tree until it
* finds a "Page" frame.
*/
static nsIFrame * GetPageFrame(nsIFrame * aFrame)
{
nsIFrame * frame = aFrame;
while (frame != nsnull) {
nsCOMPtr<nsIAtom> type;
frame->GetFrameType(getter_AddRefs(type));
if (type.get() == nsLayoutAtoms::pageFrame) {
return frame;
}
frame->GetParent(&frame);
}
return nsnull;
}
/** ---------------------------------------------------
* Find by checking content's tag type
*/
static nsIFrame * FindFrameByType(nsIPresContext* aPresContext,
nsIFrame * aParentFrame,
nsIAtom * aType,
nsRect& aRect,
nsRect& aChildRect)
{
nsIFrame * child;
nsRect rect;
aParentFrame->GetRect(rect);
aRect.x += rect.x;
aRect.y += rect.y;
aParentFrame->FirstChild(aPresContext, nsnull, &child);
while (child != nsnull) {
nsCOMPtr<nsIContent> content;
child->GetContent(getter_AddRefs(content));
if (content) {
nsCOMPtr<nsIAtom> type;
content->GetTag(*getter_AddRefs(type));
if (type.get() == aType) {
nsRect r;
child->GetRect(r);
aChildRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height);
aRect.x -= rect.x;
aRect.y -= rect.y;
return child;
}
}
nsIFrame * fndFrame = FindFrameByType(aPresContext, child, aType, aRect, aChildRect);
if (fndFrame != nsnull) {
return fndFrame;
}
child->GetNextSibling(&child);
}
aRect.x -= rect.x;
aRect.y -= rect.y;
return nsnull;
}
/** ---------------------------------------------------
* Find by checking frames type
*/
static nsresult FindSelectionBounds(nsIPresContext* aPresContext,
nsIRenderingContext& aRC,
nsIFrame * aParentFrame,
nsRect& aRect,
nsIFrame *& aStartFrame,
nsRect& aStartRect,
nsIFrame *& aEndFrame,
nsRect& aEndRect)
{
nsIFrame * child;
aParentFrame->FirstChild(aPresContext, nsnull, &child);
nsRect rect;
aParentFrame->GetRect(rect);
aRect.x += rect.x;
aRect.y += rect.y;
while (child != nsnull) {
nsFrameState state;
child->GetFrameState(&state);
// only leaf frames have this bit flipped
// then check the hard way
PRBool isSelected = (state & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (isSelected) {
if (NS_FAILED(child->IsVisibleForPainting(aPresContext, aRC, PR_TRUE, &isSelected))) {
return NS_ERROR_FAILURE;
}
}
if (isSelected) {
nsRect r;
child->GetRect(r);
if (aStartFrame == nsnull) {
aStartFrame = child;
aStartRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height);
} else {
child->GetRect(r);
aEndFrame = child;
aEndRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height);
}
}
FindSelectionBounds(aPresContext, aRC, child, aRect, aStartFrame, aStartRect, aEndFrame, aEndRect);
child->GetNextSibling(&child);
}
aRect.x -= rect.x;
aRect.y -= rect.y;
return NS_OK;
}
/** ---------------------------------------------------
* This method finds the starting and ending page numbers
* of the selection and also returns rect for each where
* the x,y of the rect is relative to the very top of the
* frame tree (absolutely positioned)
*/
static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell,
nsIPresContext* aPresContext,
nsIRenderingContext& aRC,
nsISelection* aSelection,
nsIPageSequenceFrame* aPageSeqFrame,
nsIFrame** aStartFrame,
PRInt32& aStartPageNum,
nsRect& aStartRect,
nsIFrame** aEndFrame,
PRInt32& aEndPageNum,
nsRect& aEndRect)
{
nsIFrame * seqFrame;
if (NS_FAILED(aPageSeqFrame->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) {
return NS_ERROR_FAILURE;
}
nsIFrame * startFrame = nsnull;
nsIFrame * endFrame = nsnull;
nsRect rect;
seqFrame->GetRect(rect);
// start out with the sequence frame and search the entire frame tree
// capturing the the starting and ending child frames of the selection
// and their rects
FindSelectionBounds(aPresContext, aRC, seqFrame, rect, startFrame, aStartRect, endFrame, aEndRect);
#ifdef DEBUG_rods
printf("Start Frame: %p\n", startFrame);
printf("End Frame: %p\n", endFrame);
#endif
// initial the page numbers here
// in case we don't find and frames
aStartPageNum = -1;
aEndPageNum = -1;
nsIFrame * startPageFrame;
nsIFrame * endPageFrame;
// check to make sure we found a starting frame
if (startFrame != nsnull) {
// Now search up the tree to find what page the
// start/ending selections frames are on
//
// Check to see if start should be same as end if
// the end frame comes back null
if (endFrame == nsnull) {
// XXX the "GetPageFrame" step could be integrated into
// the FindSelectionBounds step, but walking up to find
// the parent of a child frame isn't expensive and it makes
// FindSelectionBounds a little easier to understand
startPageFrame = GetPageFrame(startFrame);
endPageFrame = startPageFrame;
aEndRect = aStartRect;
} else {
startPageFrame = GetPageFrame(startFrame);
endPageFrame = GetPageFrame(endFrame);
}
} else {
return NS_ERROR_FAILURE;
}
#ifdef DEBUG_rods
printf("Start Page: %p\n", startPageFrame);
printf("End Page: %p\n", endPageFrame);
// dump all the pages and their pointers
{
PRInt32 pageNum = 1;
nsIFrame * child;
seqFrame->FirstChild(aPresContext, nsnull, &child);
while (child != nsnull) {
printf("Page: %d - %p\n", pageNum, child);
pageNum++;
child->GetNextSibling(&child);
}
}
#endif
// Now that we have the page frames
// find out what the page numbers are for each frame
PRInt32 pageNum = 1;
nsIFrame * page;
seqFrame->FirstChild(aPresContext, nsnull, &page);
while (page != nsnull) {
if (page == startPageFrame) {
aStartPageNum = pageNum;
}
if (page == endPageFrame) {
aEndPageNum = pageNum;
}
pageNum++;
page->GetNextSibling(&page);
}
#ifdef DEBUG_rods
printf("Start Page No: %d\n", aStartPageNum);
printf("End Page No: %d\n", aEndPageNum);
#endif
*aStartFrame = startPageFrame;
*aEndFrame = endPageFrame;
return NS_OK;
}
//-------------------------------------------------------
nsresult
DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
nsIDeviceContext * aDContext)
@ -889,7 +1283,6 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
nsCOMPtr<nsIStyleSet> ss;
nsCOMPtr<nsIViewManager> vm;
PRInt32 width, height;
nsIView *view;
nsresult rv;
PRInt32 count,i;
nsCOMPtr<nsIContentViewer> viewer;
@ -922,7 +1315,10 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
nsCOMPtr<nsIDocument> doc;
shell->GetDocument(getter_AddRefs(doc));
if (doc) {
nsCOMPtr<nsIContent> rootContent = getter_AddRefs(mDocument->GetRootContent());
if (mSelectionDoc) {
doc = mSelectionDoc;
}
nsCOMPtr<nsIContent> rootContent = getter_AddRefs(doc->GetRootContent());
if (rootContent) {
if (NS_SUCCEEDED(FindFrameSetWithIID(rootContent, NS_GET_IID(nsIDOMHTMLFrameSetElement)))) {
doesContainFrameSet = PR_TRUE;
@ -955,6 +1351,16 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
NS_ENSURE_SUCCESS( aDContext->BeginDocument(), NS_ERROR_FAILURE );
aDContext->GetDeviceSurfaceDimensions(width, height);
// XXX - Hack Alert
// OK, so ther eis a selection, we will print the entire selection
// on one page and then crop the page.
// This means you can never print any selection that is longer than one page
// put it keeps it from page breaking in the middle of your print of the selection
// (see also nsSimplePageSequence.cpp)
if (IsThereASelection()) {
height = 0x0FFFFFFF;
}
nsCOMPtr<nsIPresContext> cx;
nsCOMPtr<nsIPrintContext> printcon;
rv = NS_NewPrintContext(getter_AddRefs(printcon));
@ -992,17 +1398,18 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
nsRect tbounds = nsRect(0, 0, width, height);
// Create a child window of the parent that is our "root view/window"
rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&view);
nsIView* rootView;
rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&rootView);
if (NS_FAILED(rv)) {
return rv;
}
rv = view->Init(vm, tbounds, nsnull);
rv = rootView->Init(vm, tbounds, nsnull);
if (NS_FAILED(rv)) {
return rv;
}
// Setup hierarchical relationship in view manager
vm->SetRootView(view);
vm->SetRootView(rootView);
ps->Init(mDocument, cx, vm, ss);
@ -1018,10 +1425,30 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE);
presShell->CaptureHistoryState(getter_AddRefs(layoutState),PR_TRUE);
ps->BeginObservingDocument();
//lay it out...
ps->InitialReflow(width, height);
// Transfer Selection Ranges to the new Print PresShell
nsCOMPtr<nsISelection> selection;
nsCOMPtr<nsISelection> selectionPS;
GetDocumentSelection(getter_AddRefs(selection));
if (selection) {
GetDocumentSelection(ps, getter_AddRefs(selectionPS));
if (selectionPS) {
PRInt32 cnt;
selection->GetRangeCount(&cnt);
PRInt32 inx;
for (inx=0;inx<cnt;inx++) {
nsCOMPtr<nsIDOMRange> range;
if (NS_SUCCEEDED(selection->GetRangeAt(inx, getter_AddRefs(range)))) {
selectionPS->AddRange(range);
}
}
}
}
// update the history from the old presentation shell
nsCOMPtr<nsIFrameManager> fm;
rv = ps->GetFrameManager(getter_AddRefs(fm));
@ -1034,8 +1461,8 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
// Ask the page sequence frame to print all the pages
nsIPageSequenceFrame* pageSequence;
nsPrintOptions options;
//
ps->GetPageSequenceFrame(&pageSequence);
NS_ASSERTION(nsnull != pageSequence, "no page sequence frame");
@ -1051,7 +1478,97 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
}
fclose(mFilePointer);
} else {
pageSequence->Print(cx, options, nsnull);
nsIFrame* rootFrame;
ps->GetRootFrame(&rootFrame);
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
DumpLayoutData(cx, aDContext, rootFrame, aParent);
#endif
nsPrintRange printRangeType = ePrintRange_AllPages;
NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv);
if (NS_SUCCEEDED(rv) && printService) {
PRInt32 printType;
printService->GetPrintRange(&printType);
printRangeType = (nsPrintRange)printType;
// get the document title
const nsString* docTitle = mDocument->GetDocumentTitle();
PRUnichar * docStr = docTitle->ToNewUnicode();
printService->SetTitle(docStr);
nsMemory::Free(docStr);
// Get Document URL String
nsCOMPtr<nsIURI> url(getter_AddRefs(mDocument->GetDocumentURL()));
char * urlCStr;
url->GetSpec(&urlCStr);
nsAutoString urlStr;
urlStr.AssignWithConversion(urlCStr);
PRUnichar * urlUStr = urlStr.ToNewUnicode();
printService->SetURL(urlUStr);
nsMemory::Free(urlUStr);
nsMemory::Free(urlCStr);
if (ePrintRange_Selection == printRangeType) {
cx->SetIsRenderingOnlySelection(PR_TRUE);
// temporarily creating rendering context
// which is needed to dinf the selection frames
nsCOMPtr<nsIRenderingContext> rc;
aDContext->CreateRenderingContext(*getter_AddRefs(rc));
// find the starting and ending page numbers
// via the selection
nsIFrame* startFrame;
nsIFrame* endFrame;
PRInt32 startPageNum;
PRInt32 endPageNum;
nsRect startRect;
nsRect endRect;
rv = GetPageRangeForSelection(ps, cx, *rc, selectionPS, pageSequence,
&startFrame, startPageNum, startRect,
&endFrame, endPageNum, endRect);
if (NS_SUCCEEDED(rv)) {
printService->SetPageRange(startPageNum, endPageNum);
if (startPageNum == endPageNum) {
nsIFrame * seqFrame;
if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) {
return NS_ERROR_FAILURE;
}
nsRect rect(0,0,0,0);
nsRect areaRect;
nsIFrame * areaFrame = FindFrameByType(cx, startFrame, nsHTMLAtoms::body, rect, areaRect);
if (areaFrame) {
areaRect.y = areaRect.y - startRect.y;
areaFrame->SetRect(cx, areaRect);
}
}
}
}
nsIFrame * seqFrame;
if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) {
return NS_ERROR_FAILURE;
}
nsRect srect;
seqFrame->GetRect(srect);
nsRect r;
rootView->GetBounds(r);
r.height = srect.height;
rootView->SetBounds(r);
rootFrame->GetRect(r);
r.height = srect.height;
rootFrame->SetRect(cx, r);
pageSequence->Print(cx, printService, nsnull);
} else {
// not sure what to do here!
return NS_ERROR_FAILURE;
}
}
aDContext->EndDocument();
@ -1287,17 +1804,23 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget,
return rv;
}
nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection)
nsresult DocumentViewerImpl::GetDocumentSelection(nsIPresShell * aPresShell, nsISelection **aSelection)
{
if (!aSelection) return NS_ERROR_NULL_POINTER;
if (!mPresShell) return NS_ERROR_NOT_INITIALIZED;
if (!aPresShell) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsISelectionController> selcon;
selcon = do_QueryInterface(mPresShell);
selcon = do_QueryInterface(aPresShell);
if (selcon)
return selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, aSelection);
return NS_ERROR_FAILURE;
}
nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection)
{
if (!mPresShell) return NS_ERROR_NOT_INITIALIZED;
return GetDocumentSelection(mPresShell, aSelection);
}
NS_IMETHODIMP
DocumentViewerImpl::CreateDocumentViewerUsing(nsIPresContext* aPresContext,
nsIDocumentViewer*& aResult)
@ -1386,6 +1909,8 @@ void DocumentViewerImpl::DocumentReadyForPrinting()
NS_RELEASE(mPrintVM);
NS_RELEASE(mPrintSS);
NS_RELEASE(mPrintDC);
NS_IF_RELEASE(mSelectionDoc);
}
}
@ -1535,6 +2060,198 @@ DocumentViewerImpl::GetSaveable(PRBool *aSaveable)
static NS_DEFINE_IID(kDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTORY_CID);
//------------------------------------------------------------------
#include "nsINodeInfo.h"
#include "nsIDocument.h"
#include "nsHTMLAtoms.h"
#include "nsIHTMLContent.h"
#include "nsINameSpaceManager.h"
#include "nsIWebShell.h"
static NS_DEFINE_IID(kWebShellCID, NS_WEB_SHELL_CID);
static NS_DEFINE_IID(kCViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kCChildCID, NS_CHILD_CID);
#if 0
nsresult
DocumentViewerImpl::CreateDocShell(nsIPresContext* aPresContext, const nsSize& aSize)
{
nsresult rv;
mSelectionDocShell = do_CreateInstance(kWebShellCID);
NS_ENSURE_TRUE(mSelectionDocShell, NS_ERROR_FAILURE);
// pass along marginwidth and marginheight so sub document can use it
mSelectionDocShell->SetMarginWidth(0);
mSelectionDocShell->SetMarginHeight(0);
/* our parent must be a docshell. we need to get our prefs from our parent */
nsCOMPtr<nsISupports> container;
aPresContext->GetContainer(getter_AddRefs(container));
NS_ENSURE_TRUE(container, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsIDocShell> outerShell = do_QueryInterface(container);
NS_ENSURE_TRUE(outerShell, NS_ERROR_UNEXPECTED);
float t2p;
aPresContext->GetTwipsToPixels(&t2p);
nsCOMPtr<nsIPresShell> presShell;
rv = aPresContext->GetShell(getter_AddRefs(presShell));
if (NS_FAILED(rv)) { return rv; }
// create, init, set the parent of the view
nsIView* view;
rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, NS_GET_IID(nsIView),
(void **)&view);
if (NS_FAILED(rv)) { return rv; }
nsIView* parView;
nsPoint origin;
GetOffsetFromView(aPresContext, origin, &parView);
nsRect viewBounds(origin.x, origin.y, aSize.width, aSize.height);
#ifdef NOISY
printf("%p view bounds: x=%d, y=%d, w=%d, h=%d\n", view, origin.x, origin.y, aSize.width, aSize.height);
#endif
nsCOMPtr<nsIViewManager> viewMan;
presShell->GetViewManager(getter_AddRefs(viewMan));
rv = view->Init(viewMan, viewBounds, parView);
if (NS_FAILED(rv)) { return rv; }
viewMan->InsertChild(parView, view, 0);
rv = view->CreateWidget(kCChildCID);
if (NS_FAILED(rv)) { return rv; }
SetView(aPresContext, view);
// if the visibility is hidden, reflect that in the view
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
if (!display->IsVisible()) {
view->SetVisibility(nsViewVisibility_kHide);
}
const nsStyleSpacing* spacing;
GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
nsMargin border;
spacing->CalcBorderFor(this, border);
nsCOMPtr<nsIWidget> widget;
view->GetWidget(*getter_AddRefs(widget));
mSelectionDocShell->SetAllowPlugins(PR_FALSE);
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mSelectionDocShell));
PRInt32 x = NSToCoordRound(border.left * t2p);
PRInt32 y = NSToCoordRound(border.top * t2p);
PRInt32 cx = NSToCoordRound((aSize.width - border.right) * t2p);
PRInt32 cy = NSToCoordRound((aSize.height - border.bottom) * t2p);
NS_ENSURE_SUCCESS(docShellAsWin->InitWindow(nsnull, widget, (x >= 0) ? x : 0,
(y >= 0) ? y : 0, cx, cy), NS_ERROR_FAILURE);
NS_ENSURE_SUCCESS(docShellAsWin->Create(), NS_ERROR_FAILURE);
// move the view to the proper location
viewMan->MoveViewTo(view, origin.x, origin.y);
mSelectionDocShell->SetDocLoaderObserver(mTempObserver);
PRInt32 type;
GetType(&type);
if ((PR_FALSE==IsSingleLineTextControl()) || (NS_FORM_INPUT_PASSWORD == type)) {
docShellAsWin->SetVisibility(PR_TRUE);
}
return NS_OK;
}
#endif
//nsresult DocumentViewerImpl::PrintSelection(nsIDeviceContextSpec * aDevSpec)
nsresult DocumentViewerImpl::GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc)
{
//NS_ENSURE_ARG_POINTER(*aDevSpec);
NS_ENSURE_ARG_POINTER(aNewDoc);
// create document
nsCOMPtr<nsIDocument> doc;
nsresult rv = NS_NewHTMLDocument(getter_AddRefs(doc));
if (NS_FAILED(rv)) { return rv; }
if (!doc) { return NS_ERROR_NULL_POINTER; }
nsCOMPtr<nsINodeInfoManager> nimgr;
rv = doc->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsINodeInfo> nodeInfo;
nimgr->GetNodeInfo(nsHTMLAtoms::html, nsnull, kNameSpaceID_None,
*getter_AddRefs(nodeInfo));
// create document content
nsCOMPtr<nsIHTMLContent> htmlElement;
nsCOMPtr<nsIHTMLContent> headElement;
nsCOMPtr<nsIHTMLContent> bodyElement;
// create the root
rv = NS_NewHTMLHtmlElement(getter_AddRefs(htmlElement), nodeInfo);
if (NS_FAILED(rv)) { return rv; }
if (!htmlElement) { return NS_ERROR_NULL_POINTER; }
// create the head
nimgr->GetNodeInfo(NS_ConvertASCIItoUCS2("head"), nsnull,
kNameSpaceID_None, *getter_AddRefs(nodeInfo));
rv = NS_NewHTMLHeadElement(getter_AddRefs(headElement), nodeInfo);
if (NS_FAILED(rv)) { return rv; }
if (!headElement) { return NS_ERROR_NULL_POINTER; }
headElement->SetDocument(doc, PR_FALSE, PR_TRUE);
// create the body
nimgr->GetNodeInfo(nsHTMLAtoms::body, nsnull, kNameSpaceID_None,
*getter_AddRefs(nodeInfo));
rv = NS_NewHTMLBodyElement(getter_AddRefs(bodyElement), nodeInfo);
if (NS_FAILED(rv)) { return rv; }
if (!bodyElement) { return NS_ERROR_NULL_POINTER; }
bodyElement->SetDocument(doc, PR_FALSE, PR_TRUE);
// put the head and body into the root
rv = htmlElement->AppendChildTo(headElement, PR_FALSE);
if (NS_FAILED(rv)) { return rv; }
rv = htmlElement->AppendChildTo(bodyElement, PR_FALSE);
if (NS_FAILED(rv)) { return rv; }
// load the document into the docshell
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc);
if (!domDoc) { return NS_ERROR_NULL_POINTER; }
nsCOMPtr<nsIDOMElement> htmlDOMElement = do_QueryInterface(htmlElement);
if (!htmlDOMElement) { return NS_ERROR_NULL_POINTER; }
//nsCOMPtr<nsIContent> rootContent(do_QueryInterface(htmlElement));
//doc->SetRootContent(rootContent);
*aNewDoc = doc.get();
NS_ADDREF(*aNewDoc);
return rv;
}
PRBool
DocumentViewerImpl::IsThereASelection()
{
// check here to see if there is a range selection
// so we know whether to turn on the "Selection" radio button
nsCOMPtr<nsISelection> selection;
GetDocumentSelection(getter_AddRefs(selection));
if (selection) {
PRInt32 count;
selection->GetRangeCount(&count);
if (count == 1) {
nsCOMPtr<nsIDOMRange> range;
if (NS_SUCCEEDED(selection->GetRangeAt(0, getter_AddRefs(range)))) {
// check to make sure it isn't an insertion selection
PRBool isCollapsed;
selection->GetIsCollapsed(&isCollapsed);
return !isCollapsed;
}
}
}
return PR_FALSE;
}
/** ---------------------------------------------------
* See documentation above in the nsIContentViewerfile class definition
@ -1543,9 +2260,15 @@ static NS_DEFINE_IID(kDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTOR
NS_IMETHODIMP
DocumentViewerImpl::Print(PRBool aSilent,FILE *aFile, nsIPrintListener *aPrintListener)
{
nsCOMPtr<nsIWebShell> webContainer;
nsCOMPtr<nsIDeviceContextSpecFactory> factory;
PRInt32 width,height;
nsCOMPtr<nsIWebShell> webContainer;
nsCOMPtr<nsIDeviceContextSpecFactory> factory;
PRInt32 width,height;
nsresult rv = NS_ERROR_FAILURE;
NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv);
if (NS_SUCCEEDED(rv) && printService) {
printService->SetPrintOptions(NS_PRINT_OPTIONS_ENABLE_SELECTION_RADIO, IsThereASelection());
}
nsComponentManager::CreateInstance(kDeviceContextSpecFactoryCID,
nsnull,
@ -1566,11 +2289,14 @@ PRInt32 width,height;
factory->CreateDeviceContextSpec(nsnull, devspec, aSilent);
if (nsnull != devspec) {
mPresContext->GetDeviceContext(getter_AddRefs(dx));
nsresult rv = dx->GetDeviceContextFor(devspec, mPrintDC);
rv = dx->GetDeviceContextFor(devspec, mPrintDC);
if (NS_SUCCEEDED(rv)) {
NS_RELEASE(devspec);
nsCOMPtr<nsIDocument> printDoc;
printDoc = mDocument;
// Get the webshell for this documentviewer
webContainer = do_QueryInterface(mContainer);
if(webContainer) {
@ -1588,15 +2314,24 @@ PRInt32 width,height;
mPrintDC->GetDeviceSurfaceDimensions(width,height);
// XXX - Hack Alert
// OK, so ther eis a selection, we will print the entire selection
// on one page and then crop the page.
// This means you can never print any selection that is longer than one page
// put it keeps it from page breaking in the middle of your print of the selection
if (IsThereASelection()) {
height = 0x0FFFFFFF;
}
mPrintPC->Init(mPrintDC);
mPrintPC->SetContainer(webContainer);
CreateStyleSet(mDocument,&mPrintSS);
CreateStyleSet(printDoc,&mPrintSS);
rv = NS_NewPresShell(&mPrintPS);
if(NS_FAILED(rv)){
return rv;
}
rv = nsComponentManager::CreateInstance(kViewManagerCID, nsnull, NS_GET_IID(nsIViewManager),(void**)&mPrintVM);
if(NS_FAILED(rv)) {
return rv;
@ -1611,7 +2346,7 @@ PRInt32 width,height;
if(NS_FAILED(rv)) {
return rv;
}
nsRect tbounds = nsRect(0,0,width,height);
rv = mPrintView->Init(mPrintVM,tbounds,nsnull);
if(NS_FAILED(rv)) {
@ -1620,7 +2355,7 @@ PRInt32 width,height;
// setup hierarchical relationship in view manager
mPrintVM->SetRootView(mPrintView);
mPrintPS->Init(mDocument,mPrintPC,mPrintVM,mPrintSS);
mPrintPS->Init(printDoc,mPrintPC,mPrintVM,mPrintSS);
nsCOMPtr<nsIImageGroup> imageGroup;
mPrintPC->GetImageGroup(getter_AddRefs(imageGroup));

View File

@ -123,6 +123,7 @@ nsPresContext::nsPresContext()
mDefaultBackgroundImageOffsetX = mDefaultBackgroundImageOffsetY = 0;
mDefaultDirection = NS_STYLE_DIRECTION_LTR;
mLanguageSpecificTransformType = eLanguageSpecificTransformType_Unknown;
mIsRenderingOnlySelection = PR_FALSE;
}
nsPresContext::~nsPresContext()
@ -1313,6 +1314,15 @@ nsPresContext::GetLanguageSpecificTransformType(
return NS_OK;
}
NS_IMETHODIMP
nsPresContext::IsRenderingOnlySelection(PRBool* aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = mIsRenderingOnlySelection;
return NS_OK;
}
#ifdef MOZ_REFLOW_PERF
NS_IMETHODIMP
nsPresContext::CountReflows(const char * aName, PRUint32 aType)

View File

@ -357,6 +357,12 @@ public:
NS_IMETHOD GetLanguageSpecificTransformType(
nsLanguageSpecificTransformType* aType) = 0;
/**
* Render only Selection
*/
NS_IMETHOD SetIsRenderingOnlySelection(PRBool aResult) = 0;
NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0;
#ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType) = 0;
#endif

View File

@ -1092,6 +1092,19 @@ public:
nsIFrame** aProviderFrame,
nsContextProviderRelationship& aRelationship) = 0;
/**
* Determines whether a frame is visible for painting
* this takes into acount whether it is painting selection for printin
* @param aPresContext PresContext
* @param aRenderingContext PresContext
* @param aCheckVis indicates whether it should check for CSS visibility,
* PR_FALSE skips the check, PR_TRUE does the check
* @param aIsVisible return value
*/
NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aCheckVis,
PRBool* aIsVisible) = 0;
private:
NS_IMETHOD_(nsrefcnt) AddRef(void) = 0;
NS_IMETHOD_(nsrefcnt) Release(void) = 0;

View File

@ -26,6 +26,7 @@
#include "nsISupports.h"
class nsIPresContext;
class nsIPrintOptions;
// IID for the nsIPageSequenceFrame interface
// a6cf90d2-15b3-11d2-932e-00805f8add32
@ -91,27 +92,6 @@ public:
//----------------------------------------------------------------------
enum nsPrintRange {
ePrintRange_AllPages, // print all pages
ePrintRange_SpecifiedRange // only print pages in the specified range
};
/**
* Structure containing options for printing.
*/
struct nsPrintOptions {
nsPrintRange range;
PRInt32 startPage, endPage; // only used for ePrintRange_SpecifiedRange
PRPackedBool oddNumberedPages; // print the odd-numbered pages
PRPackedBool evenNumberedPages; // print the even-numbered pages
nsPrintOptions() {
range = ePrintRange_AllPages;
startPage = endPage = 1;
oddNumberedPages = evenNumberedPages = PR_TRUE;
}
};
/**
* Interface for accessing special capabilities of the page sequence frame.
*
@ -136,7 +116,7 @@ public:
* @see nsIPrintStatusCallback#OnProgress()
*/
NS_IMETHOD Print(nsIPresContext* aPresContext,
const nsPrintOptions& aPrintOptions,
nsIPrintOptions* aPrintOptions,
nsIPrintStatusCallback* aStatusCallback) = 0;
private:

View File

@ -357,6 +357,12 @@ public:
NS_IMETHOD GetLanguageSpecificTransformType(
nsLanguageSpecificTransformType* aType) = 0;
/**
* Render only Selection
*/
NS_IMETHOD SetIsRenderingOnlySelection(PRBool aResult) = 0;
NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0;
#ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType) = 0;
#endif

View File

@ -357,6 +357,12 @@ public:
NS_IMETHOD GetLanguageSpecificTransformType(
nsLanguageSpecificTransformType* aType) = 0;
/**
* Render only Selection
*/
NS_IMETHOD SetIsRenderingOnlySelection(PRBool aResult) = 0;
NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0;
#ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType) = 0;
#endif

View File

@ -87,6 +87,13 @@
#include "nsIEventQueueService.h"
#include "nsIEventQueue.h"
// Print Options
#include "nsIPrintOptions.h"
#include "nsGfxCIID.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID);
#include "nsHTMLAtoms.h" // XXX until atoms get factored into nsLayoutAtoms
//focus
#include "nsIDOMEventReceiver.h"
#include "nsIDOMFocusListener.h"
@ -248,12 +255,16 @@ private:
const nsRect& aBounds);
nsresult GetDocumentSelection(nsISelection **aSelection);
nsresult GetDocumentSelection(nsIPresShell * aPresShell, nsISelection **aSelection);
nsresult FindFrameSetWithIID(nsIContent * aParentContent, const nsIID& aIID);
PRBool IsThereASelection();
//
// The following three methods are used for printing...
//
void DocumentReadyForPrinting();
//nsresult PrintSelection(nsIDeviceContextSpec * aDevSpec);
nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc);
static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent);
static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent);
@ -297,6 +308,8 @@ protected:
nsIViewManager *mPrintVM;
nsIView *mPrintView;
FILE *mFilePointer; // a file where information can go to when printing
nsIDocument *mSelectionDoc;
nsIDocShell *mSelectionDocShell;
nsCOMPtr<nsIPrintListener> mPrintListener; // An observer for printing...
@ -339,6 +352,7 @@ DocumentViewerImpl::DocumentViewerImpl()
mEnableRendering = PR_TRUE;
mFilePointer = nsnull;
mPrintListener = nsnull;
mSelectionDoc = nsnull;
}
DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext)
@ -879,6 +893,386 @@ DocumentViewerImpl::FindFrameSetWithIID(nsIContent * aParentContent, const nsIID
return NS_ERROR_FAILURE;
}
//---------------------------------------------------------------
//---------------------------------------------------------------
//-- Debug helper routines
//---------------------------------------------------------------
//---------------------------------------------------------------
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
/** ---------------------------------------------------
* Dumps Frames for Printing
*/
static void DumpFrames(FILE* out,
nsIPresContext* aPresContext,
nsIRenderingContext * aRendContext,
nsIFrame * aFrame,
PRInt32 aLevel)
{
nsIFrame * child;
aFrame->FirstChild(aPresContext, nsnull, &child);
while (child != nsnull) {
for (PRInt32 i=0;i<aLevel;i++) {
fprintf(out, " ");
}
nsAutoString tmp;
nsIFrameDebug* frameDebug;
if (NS_SUCCEEDED(child->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) {
frameDebug->GetFrameName(tmp);
}
fputs(tmp, out);
nsFrameState state;
child->GetFrameState(&state);
PRBool isSelected;
if (NS_SUCCEEDED(child->IsVisibleForPainting(aPresContext, *aRendContext, PR_TRUE, &isSelected))) {
fprintf(out, " %p %s", child, isSelected?"VIS":"UVS");
nsRect rect;
child->GetRect(rect);
fprintf(out, "[%d,%d,%d,%d] ", rect.x, rect.y, rect.width, rect.height);
nsIView * view;
child->GetView(aPresContext, &view);
fprintf(out, "v: %p ", view);
fprintf(out, "\n");
DumpFrames(out, aPresContext, aRendContext, child, aLevel+1);
child->GetNextSibling(&child);
}
}
}
/** ---------------------------------------------------
* Helper function needed for "DumpViews"
*/
static nsIPresShell*
GetPresShellFor(nsIDocShell* aDocShell)
{
nsIPresShell* shell = nsnull;
if (nsnull != aDocShell) {
nsIContentViewer* cv = nsnull;
aDocShell->GetContentViewer(&cv);
if (nsnull != cv) {
nsIDocumentViewer* docv = nsnull;
cv->QueryInterface(NS_GET_IID(nsIDocumentViewer), (void**) &docv);
if (nsnull != docv) {
nsIPresContext* cx;
docv->GetPresContext(cx);
if (nsnull != cx) {
cx->GetShell(&shell);
NS_RELEASE(cx);
}
NS_RELEASE(docv);
}
NS_RELEASE(cv);
}
}
return shell;
}
/** ---------------------------------------------------
* Dumps the Views from the DocShell
*/
static void
DumpViews(nsIDocShell* aDocShell, FILE* out)
{
if (nsnull != aDocShell) {
fprintf(out, "docshell=%p \n", aDocShell);
nsIPresShell* shell = GetPresShellFor(aDocShell);
if (nsnull != shell) {
nsCOMPtr<nsIViewManager> vm;
shell->GetViewManager(getter_AddRefs(vm));
if (vm) {
nsIView* root;
vm->GetRootView(root);
if (nsnull != root) {
root->List(out);
}
}
NS_RELEASE(shell);
}
else {
fputs("null pres shell\n", out);
}
// dump the views of the sub documents
PRInt32 i, n;
nsCOMPtr<nsIDocShellTreeNode> docShellAsNode(do_QueryInterface(aDocShell));
docShellAsNode->GetChildCount(&n);
for (i = 0; i < n; i++) {
nsCOMPtr<nsIDocShellTreeItem> child;
docShellAsNode->GetChildAt(i, getter_AddRefs(child));
nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
if (childAsShell) {
DumpViews(childAsShell, out);
}
}
}
}
/** ---------------------------------------------------
* Dumps the Views and Frames
*/
void DumpLayoutData(nsIPresContext* aPresContext,
nsIDeviceContext * aDC,
nsIFrame * aRootFrame,
nsIWebShell * aWebShell)
{
// Dump all the frames and view to a a file
FILE * fd = fopen("dump.txt", "w");
if (fd) {
fprintf(fd, "--------------- Frames ----------------\n");
nsCOMPtr<nsIRenderingContext> renderingContext;
aDC->CreateRenderingContext(*getter_AddRefs(renderingContext));
DumpFrames(fd, aPresContext, renderingContext, aRootFrame, 0);
fprintf(fd, "---------------------------------------\n\n");
fprintf(fd, "--------------- Views From Root Frame----------------\n");
nsIView * v;
aRootFrame->GetView(aPresContext, &v);
if (v) {
v->List(fd);
} else {
printf("View is null!\n");
}
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aWebShell));
if (docShell) {
fprintf(fd, "--------------- All Views ----------------\n");
DumpViews(docShell, fd);
fprintf(fd, "---------------------------------------\n\n");
}
fclose(fd);
}
}
#endif
//---------------------------------------------------------------
//---------------------------------------------------------------
//-- End of debug helper routines
//---------------------------------------------------------------
//---------------------------------------------------------------
/** ---------------------------------------------------
* Giving a child frame it searches "up" the tree until it
* finds a "Page" frame.
*/
static nsIFrame * GetPageFrame(nsIFrame * aFrame)
{
nsIFrame * frame = aFrame;
while (frame != nsnull) {
nsCOMPtr<nsIAtom> type;
frame->GetFrameType(getter_AddRefs(type));
if (type.get() == nsLayoutAtoms::pageFrame) {
return frame;
}
frame->GetParent(&frame);
}
return nsnull;
}
/** ---------------------------------------------------
* Find by checking content's tag type
*/
static nsIFrame * FindFrameByType(nsIPresContext* aPresContext,
nsIFrame * aParentFrame,
nsIAtom * aType,
nsRect& aRect,
nsRect& aChildRect)
{
nsIFrame * child;
nsRect rect;
aParentFrame->GetRect(rect);
aRect.x += rect.x;
aRect.y += rect.y;
aParentFrame->FirstChild(aPresContext, nsnull, &child);
while (child != nsnull) {
nsCOMPtr<nsIContent> content;
child->GetContent(getter_AddRefs(content));
if (content) {
nsCOMPtr<nsIAtom> type;
content->GetTag(*getter_AddRefs(type));
if (type.get() == aType) {
nsRect r;
child->GetRect(r);
aChildRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height);
aRect.x -= rect.x;
aRect.y -= rect.y;
return child;
}
}
nsIFrame * fndFrame = FindFrameByType(aPresContext, child, aType, aRect, aChildRect);
if (fndFrame != nsnull) {
return fndFrame;
}
child->GetNextSibling(&child);
}
aRect.x -= rect.x;
aRect.y -= rect.y;
return nsnull;
}
/** ---------------------------------------------------
* Find by checking frames type
*/
static nsresult FindSelectionBounds(nsIPresContext* aPresContext,
nsIRenderingContext& aRC,
nsIFrame * aParentFrame,
nsRect& aRect,
nsIFrame *& aStartFrame,
nsRect& aStartRect,
nsIFrame *& aEndFrame,
nsRect& aEndRect)
{
nsIFrame * child;
aParentFrame->FirstChild(aPresContext, nsnull, &child);
nsRect rect;
aParentFrame->GetRect(rect);
aRect.x += rect.x;
aRect.y += rect.y;
while (child != nsnull) {
nsFrameState state;
child->GetFrameState(&state);
// only leaf frames have this bit flipped
// then check the hard way
PRBool isSelected = (state & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (isSelected) {
if (NS_FAILED(child->IsVisibleForPainting(aPresContext, aRC, PR_TRUE, &isSelected))) {
return NS_ERROR_FAILURE;
}
}
if (isSelected) {
nsRect r;
child->GetRect(r);
if (aStartFrame == nsnull) {
aStartFrame = child;
aStartRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height);
} else {
child->GetRect(r);
aEndFrame = child;
aEndRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height);
}
}
FindSelectionBounds(aPresContext, aRC, child, aRect, aStartFrame, aStartRect, aEndFrame, aEndRect);
child->GetNextSibling(&child);
}
aRect.x -= rect.x;
aRect.y -= rect.y;
return NS_OK;
}
/** ---------------------------------------------------
* This method finds the starting and ending page numbers
* of the selection and also returns rect for each where
* the x,y of the rect is relative to the very top of the
* frame tree (absolutely positioned)
*/
static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell,
nsIPresContext* aPresContext,
nsIRenderingContext& aRC,
nsISelection* aSelection,
nsIPageSequenceFrame* aPageSeqFrame,
nsIFrame** aStartFrame,
PRInt32& aStartPageNum,
nsRect& aStartRect,
nsIFrame** aEndFrame,
PRInt32& aEndPageNum,
nsRect& aEndRect)
{
nsIFrame * seqFrame;
if (NS_FAILED(aPageSeqFrame->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) {
return NS_ERROR_FAILURE;
}
nsIFrame * startFrame = nsnull;
nsIFrame * endFrame = nsnull;
nsRect rect;
seqFrame->GetRect(rect);
// start out with the sequence frame and search the entire frame tree
// capturing the the starting and ending child frames of the selection
// and their rects
FindSelectionBounds(aPresContext, aRC, seqFrame, rect, startFrame, aStartRect, endFrame, aEndRect);
#ifdef DEBUG_rods
printf("Start Frame: %p\n", startFrame);
printf("End Frame: %p\n", endFrame);
#endif
// initial the page numbers here
// in case we don't find and frames
aStartPageNum = -1;
aEndPageNum = -1;
nsIFrame * startPageFrame;
nsIFrame * endPageFrame;
// check to make sure we found a starting frame
if (startFrame != nsnull) {
// Now search up the tree to find what page the
// start/ending selections frames are on
//
// Check to see if start should be same as end if
// the end frame comes back null
if (endFrame == nsnull) {
// XXX the "GetPageFrame" step could be integrated into
// the FindSelectionBounds step, but walking up to find
// the parent of a child frame isn't expensive and it makes
// FindSelectionBounds a little easier to understand
startPageFrame = GetPageFrame(startFrame);
endPageFrame = startPageFrame;
aEndRect = aStartRect;
} else {
startPageFrame = GetPageFrame(startFrame);
endPageFrame = GetPageFrame(endFrame);
}
} else {
return NS_ERROR_FAILURE;
}
#ifdef DEBUG_rods
printf("Start Page: %p\n", startPageFrame);
printf("End Page: %p\n", endPageFrame);
// dump all the pages and their pointers
{
PRInt32 pageNum = 1;
nsIFrame * child;
seqFrame->FirstChild(aPresContext, nsnull, &child);
while (child != nsnull) {
printf("Page: %d - %p\n", pageNum, child);
pageNum++;
child->GetNextSibling(&child);
}
}
#endif
// Now that we have the page frames
// find out what the page numbers are for each frame
PRInt32 pageNum = 1;
nsIFrame * page;
seqFrame->FirstChild(aPresContext, nsnull, &page);
while (page != nsnull) {
if (page == startPageFrame) {
aStartPageNum = pageNum;
}
if (page == endPageFrame) {
aEndPageNum = pageNum;
}
pageNum++;
page->GetNextSibling(&page);
}
#ifdef DEBUG_rods
printf("Start Page No: %d\n", aStartPageNum);
printf("End Page No: %d\n", aEndPageNum);
#endif
*aStartFrame = startPageFrame;
*aEndFrame = endPageFrame;
return NS_OK;
}
//-------------------------------------------------------
nsresult
DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
nsIDeviceContext * aDContext)
@ -889,7 +1283,6 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
nsCOMPtr<nsIStyleSet> ss;
nsCOMPtr<nsIViewManager> vm;
PRInt32 width, height;
nsIView *view;
nsresult rv;
PRInt32 count,i;
nsCOMPtr<nsIContentViewer> viewer;
@ -922,7 +1315,10 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
nsCOMPtr<nsIDocument> doc;
shell->GetDocument(getter_AddRefs(doc));
if (doc) {
nsCOMPtr<nsIContent> rootContent = getter_AddRefs(mDocument->GetRootContent());
if (mSelectionDoc) {
doc = mSelectionDoc;
}
nsCOMPtr<nsIContent> rootContent = getter_AddRefs(doc->GetRootContent());
if (rootContent) {
if (NS_SUCCEEDED(FindFrameSetWithIID(rootContent, NS_GET_IID(nsIDOMHTMLFrameSetElement)))) {
doesContainFrameSet = PR_TRUE;
@ -955,6 +1351,16 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
NS_ENSURE_SUCCESS( aDContext->BeginDocument(), NS_ERROR_FAILURE );
aDContext->GetDeviceSurfaceDimensions(width, height);
// XXX - Hack Alert
// OK, so ther eis a selection, we will print the entire selection
// on one page and then crop the page.
// This means you can never print any selection that is longer than one page
// put it keeps it from page breaking in the middle of your print of the selection
// (see also nsSimplePageSequence.cpp)
if (IsThereASelection()) {
height = 0x0FFFFFFF;
}
nsCOMPtr<nsIPresContext> cx;
nsCOMPtr<nsIPrintContext> printcon;
rv = NS_NewPrintContext(getter_AddRefs(printcon));
@ -992,17 +1398,18 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
nsRect tbounds = nsRect(0, 0, width, height);
// Create a child window of the parent that is our "root view/window"
rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&view);
nsIView* rootView;
rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&rootView);
if (NS_FAILED(rv)) {
return rv;
}
rv = view->Init(vm, tbounds, nsnull);
rv = rootView->Init(vm, tbounds, nsnull);
if (NS_FAILED(rv)) {
return rv;
}
// Setup hierarchical relationship in view manager
vm->SetRootView(view);
vm->SetRootView(rootView);
ps->Init(mDocument, cx, vm, ss);
@ -1018,10 +1425,30 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE);
presShell->CaptureHistoryState(getter_AddRefs(layoutState),PR_TRUE);
ps->BeginObservingDocument();
//lay it out...
ps->InitialReflow(width, height);
// Transfer Selection Ranges to the new Print PresShell
nsCOMPtr<nsISelection> selection;
nsCOMPtr<nsISelection> selectionPS;
GetDocumentSelection(getter_AddRefs(selection));
if (selection) {
GetDocumentSelection(ps, getter_AddRefs(selectionPS));
if (selectionPS) {
PRInt32 cnt;
selection->GetRangeCount(&cnt);
PRInt32 inx;
for (inx=0;inx<cnt;inx++) {
nsCOMPtr<nsIDOMRange> range;
if (NS_SUCCEEDED(selection->GetRangeAt(inx, getter_AddRefs(range)))) {
selectionPS->AddRange(range);
}
}
}
}
// update the history from the old presentation shell
nsCOMPtr<nsIFrameManager> fm;
rv = ps->GetFrameManager(getter_AddRefs(fm));
@ -1034,8 +1461,8 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
// Ask the page sequence frame to print all the pages
nsIPageSequenceFrame* pageSequence;
nsPrintOptions options;
//
ps->GetPageSequenceFrame(&pageSequence);
NS_ASSERTION(nsnull != pageSequence, "no page sequence frame");
@ -1051,7 +1478,97 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent,
}
fclose(mFilePointer);
} else {
pageSequence->Print(cx, options, nsnull);
nsIFrame* rootFrame;
ps->GetRootFrame(&rootFrame);
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
DumpLayoutData(cx, aDContext, rootFrame, aParent);
#endif
nsPrintRange printRangeType = ePrintRange_AllPages;
NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv);
if (NS_SUCCEEDED(rv) && printService) {
PRInt32 printType;
printService->GetPrintRange(&printType);
printRangeType = (nsPrintRange)printType;
// get the document title
const nsString* docTitle = mDocument->GetDocumentTitle();
PRUnichar * docStr = docTitle->ToNewUnicode();
printService->SetTitle(docStr);
nsMemory::Free(docStr);
// Get Document URL String
nsCOMPtr<nsIURI> url(getter_AddRefs(mDocument->GetDocumentURL()));
char * urlCStr;
url->GetSpec(&urlCStr);
nsAutoString urlStr;
urlStr.AssignWithConversion(urlCStr);
PRUnichar * urlUStr = urlStr.ToNewUnicode();
printService->SetURL(urlUStr);
nsMemory::Free(urlUStr);
nsMemory::Free(urlCStr);
if (ePrintRange_Selection == printRangeType) {
cx->SetIsRenderingOnlySelection(PR_TRUE);
// temporarily creating rendering context
// which is needed to dinf the selection frames
nsCOMPtr<nsIRenderingContext> rc;
aDContext->CreateRenderingContext(*getter_AddRefs(rc));
// find the starting and ending page numbers
// via the selection
nsIFrame* startFrame;
nsIFrame* endFrame;
PRInt32 startPageNum;
PRInt32 endPageNum;
nsRect startRect;
nsRect endRect;
rv = GetPageRangeForSelection(ps, cx, *rc, selectionPS, pageSequence,
&startFrame, startPageNum, startRect,
&endFrame, endPageNum, endRect);
if (NS_SUCCEEDED(rv)) {
printService->SetPageRange(startPageNum, endPageNum);
if (startPageNum == endPageNum) {
nsIFrame * seqFrame;
if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) {
return NS_ERROR_FAILURE;
}
nsRect rect(0,0,0,0);
nsRect areaRect;
nsIFrame * areaFrame = FindFrameByType(cx, startFrame, nsHTMLAtoms::body, rect, areaRect);
if (areaFrame) {
areaRect.y = areaRect.y - startRect.y;
areaFrame->SetRect(cx, areaRect);
}
}
}
}
nsIFrame * seqFrame;
if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) {
return NS_ERROR_FAILURE;
}
nsRect srect;
seqFrame->GetRect(srect);
nsRect r;
rootView->GetBounds(r);
r.height = srect.height;
rootView->SetBounds(r);
rootFrame->GetRect(r);
r.height = srect.height;
rootFrame->SetRect(cx, r);
pageSequence->Print(cx, printService, nsnull);
} else {
// not sure what to do here!
return NS_ERROR_FAILURE;
}
}
aDContext->EndDocument();
@ -1287,17 +1804,23 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget,
return rv;
}
nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection)
nsresult DocumentViewerImpl::GetDocumentSelection(nsIPresShell * aPresShell, nsISelection **aSelection)
{
if (!aSelection) return NS_ERROR_NULL_POINTER;
if (!mPresShell) return NS_ERROR_NOT_INITIALIZED;
if (!aPresShell) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsISelectionController> selcon;
selcon = do_QueryInterface(mPresShell);
selcon = do_QueryInterface(aPresShell);
if (selcon)
return selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, aSelection);
return NS_ERROR_FAILURE;
}
nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection)
{
if (!mPresShell) return NS_ERROR_NOT_INITIALIZED;
return GetDocumentSelection(mPresShell, aSelection);
}
NS_IMETHODIMP
DocumentViewerImpl::CreateDocumentViewerUsing(nsIPresContext* aPresContext,
nsIDocumentViewer*& aResult)
@ -1386,6 +1909,8 @@ void DocumentViewerImpl::DocumentReadyForPrinting()
NS_RELEASE(mPrintVM);
NS_RELEASE(mPrintSS);
NS_RELEASE(mPrintDC);
NS_IF_RELEASE(mSelectionDoc);
}
}
@ -1535,6 +2060,198 @@ DocumentViewerImpl::GetSaveable(PRBool *aSaveable)
static NS_DEFINE_IID(kDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTORY_CID);
//------------------------------------------------------------------
#include "nsINodeInfo.h"
#include "nsIDocument.h"
#include "nsHTMLAtoms.h"
#include "nsIHTMLContent.h"
#include "nsINameSpaceManager.h"
#include "nsIWebShell.h"
static NS_DEFINE_IID(kWebShellCID, NS_WEB_SHELL_CID);
static NS_DEFINE_IID(kCViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kCChildCID, NS_CHILD_CID);
#if 0
nsresult
DocumentViewerImpl::CreateDocShell(nsIPresContext* aPresContext, const nsSize& aSize)
{
nsresult rv;
mSelectionDocShell = do_CreateInstance(kWebShellCID);
NS_ENSURE_TRUE(mSelectionDocShell, NS_ERROR_FAILURE);
// pass along marginwidth and marginheight so sub document can use it
mSelectionDocShell->SetMarginWidth(0);
mSelectionDocShell->SetMarginHeight(0);
/* our parent must be a docshell. we need to get our prefs from our parent */
nsCOMPtr<nsISupports> container;
aPresContext->GetContainer(getter_AddRefs(container));
NS_ENSURE_TRUE(container, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsIDocShell> outerShell = do_QueryInterface(container);
NS_ENSURE_TRUE(outerShell, NS_ERROR_UNEXPECTED);
float t2p;
aPresContext->GetTwipsToPixels(&t2p);
nsCOMPtr<nsIPresShell> presShell;
rv = aPresContext->GetShell(getter_AddRefs(presShell));
if (NS_FAILED(rv)) { return rv; }
// create, init, set the parent of the view
nsIView* view;
rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, NS_GET_IID(nsIView),
(void **)&view);
if (NS_FAILED(rv)) { return rv; }
nsIView* parView;
nsPoint origin;
GetOffsetFromView(aPresContext, origin, &parView);
nsRect viewBounds(origin.x, origin.y, aSize.width, aSize.height);
#ifdef NOISY
printf("%p view bounds: x=%d, y=%d, w=%d, h=%d\n", view, origin.x, origin.y, aSize.width, aSize.height);
#endif
nsCOMPtr<nsIViewManager> viewMan;
presShell->GetViewManager(getter_AddRefs(viewMan));
rv = view->Init(viewMan, viewBounds, parView);
if (NS_FAILED(rv)) { return rv; }
viewMan->InsertChild(parView, view, 0);
rv = view->CreateWidget(kCChildCID);
if (NS_FAILED(rv)) { return rv; }
SetView(aPresContext, view);
// if the visibility is hidden, reflect that in the view
const nsStyleDisplay* display;
GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
if (!display->IsVisible()) {
view->SetVisibility(nsViewVisibility_kHide);
}
const nsStyleSpacing* spacing;
GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
nsMargin border;
spacing->CalcBorderFor(this, border);
nsCOMPtr<nsIWidget> widget;
view->GetWidget(*getter_AddRefs(widget));
mSelectionDocShell->SetAllowPlugins(PR_FALSE);
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mSelectionDocShell));
PRInt32 x = NSToCoordRound(border.left * t2p);
PRInt32 y = NSToCoordRound(border.top * t2p);
PRInt32 cx = NSToCoordRound((aSize.width - border.right) * t2p);
PRInt32 cy = NSToCoordRound((aSize.height - border.bottom) * t2p);
NS_ENSURE_SUCCESS(docShellAsWin->InitWindow(nsnull, widget, (x >= 0) ? x : 0,
(y >= 0) ? y : 0, cx, cy), NS_ERROR_FAILURE);
NS_ENSURE_SUCCESS(docShellAsWin->Create(), NS_ERROR_FAILURE);
// move the view to the proper location
viewMan->MoveViewTo(view, origin.x, origin.y);
mSelectionDocShell->SetDocLoaderObserver(mTempObserver);
PRInt32 type;
GetType(&type);
if ((PR_FALSE==IsSingleLineTextControl()) || (NS_FORM_INPUT_PASSWORD == type)) {
docShellAsWin->SetVisibility(PR_TRUE);
}
return NS_OK;
}
#endif
//nsresult DocumentViewerImpl::PrintSelection(nsIDeviceContextSpec * aDevSpec)
nsresult DocumentViewerImpl::GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc)
{
//NS_ENSURE_ARG_POINTER(*aDevSpec);
NS_ENSURE_ARG_POINTER(aNewDoc);
// create document
nsCOMPtr<nsIDocument> doc;
nsresult rv = NS_NewHTMLDocument(getter_AddRefs(doc));
if (NS_FAILED(rv)) { return rv; }
if (!doc) { return NS_ERROR_NULL_POINTER; }
nsCOMPtr<nsINodeInfoManager> nimgr;
rv = doc->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsINodeInfo> nodeInfo;
nimgr->GetNodeInfo(nsHTMLAtoms::html, nsnull, kNameSpaceID_None,
*getter_AddRefs(nodeInfo));
// create document content
nsCOMPtr<nsIHTMLContent> htmlElement;
nsCOMPtr<nsIHTMLContent> headElement;
nsCOMPtr<nsIHTMLContent> bodyElement;
// create the root
rv = NS_NewHTMLHtmlElement(getter_AddRefs(htmlElement), nodeInfo);
if (NS_FAILED(rv)) { return rv; }
if (!htmlElement) { return NS_ERROR_NULL_POINTER; }
// create the head
nimgr->GetNodeInfo(NS_ConvertASCIItoUCS2("head"), nsnull,
kNameSpaceID_None, *getter_AddRefs(nodeInfo));
rv = NS_NewHTMLHeadElement(getter_AddRefs(headElement), nodeInfo);
if (NS_FAILED(rv)) { return rv; }
if (!headElement) { return NS_ERROR_NULL_POINTER; }
headElement->SetDocument(doc, PR_FALSE, PR_TRUE);
// create the body
nimgr->GetNodeInfo(nsHTMLAtoms::body, nsnull, kNameSpaceID_None,
*getter_AddRefs(nodeInfo));
rv = NS_NewHTMLBodyElement(getter_AddRefs(bodyElement), nodeInfo);
if (NS_FAILED(rv)) { return rv; }
if (!bodyElement) { return NS_ERROR_NULL_POINTER; }
bodyElement->SetDocument(doc, PR_FALSE, PR_TRUE);
// put the head and body into the root
rv = htmlElement->AppendChildTo(headElement, PR_FALSE);
if (NS_FAILED(rv)) { return rv; }
rv = htmlElement->AppendChildTo(bodyElement, PR_FALSE);
if (NS_FAILED(rv)) { return rv; }
// load the document into the docshell
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc);
if (!domDoc) { return NS_ERROR_NULL_POINTER; }
nsCOMPtr<nsIDOMElement> htmlDOMElement = do_QueryInterface(htmlElement);
if (!htmlDOMElement) { return NS_ERROR_NULL_POINTER; }
//nsCOMPtr<nsIContent> rootContent(do_QueryInterface(htmlElement));
//doc->SetRootContent(rootContent);
*aNewDoc = doc.get();
NS_ADDREF(*aNewDoc);
return rv;
}
PRBool
DocumentViewerImpl::IsThereASelection()
{
// check here to see if there is a range selection
// so we know whether to turn on the "Selection" radio button
nsCOMPtr<nsISelection> selection;
GetDocumentSelection(getter_AddRefs(selection));
if (selection) {
PRInt32 count;
selection->GetRangeCount(&count);
if (count == 1) {
nsCOMPtr<nsIDOMRange> range;
if (NS_SUCCEEDED(selection->GetRangeAt(0, getter_AddRefs(range)))) {
// check to make sure it isn't an insertion selection
PRBool isCollapsed;
selection->GetIsCollapsed(&isCollapsed);
return !isCollapsed;
}
}
}
return PR_FALSE;
}
/** ---------------------------------------------------
* See documentation above in the nsIContentViewerfile class definition
@ -1543,9 +2260,15 @@ static NS_DEFINE_IID(kDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTOR
NS_IMETHODIMP
DocumentViewerImpl::Print(PRBool aSilent,FILE *aFile, nsIPrintListener *aPrintListener)
{
nsCOMPtr<nsIWebShell> webContainer;
nsCOMPtr<nsIDeviceContextSpecFactory> factory;
PRInt32 width,height;
nsCOMPtr<nsIWebShell> webContainer;
nsCOMPtr<nsIDeviceContextSpecFactory> factory;
PRInt32 width,height;
nsresult rv = NS_ERROR_FAILURE;
NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv);
if (NS_SUCCEEDED(rv) && printService) {
printService->SetPrintOptions(NS_PRINT_OPTIONS_ENABLE_SELECTION_RADIO, IsThereASelection());
}
nsComponentManager::CreateInstance(kDeviceContextSpecFactoryCID,
nsnull,
@ -1566,11 +2289,14 @@ PRInt32 width,height;
factory->CreateDeviceContextSpec(nsnull, devspec, aSilent);
if (nsnull != devspec) {
mPresContext->GetDeviceContext(getter_AddRefs(dx));
nsresult rv = dx->GetDeviceContextFor(devspec, mPrintDC);
rv = dx->GetDeviceContextFor(devspec, mPrintDC);
if (NS_SUCCEEDED(rv)) {
NS_RELEASE(devspec);
nsCOMPtr<nsIDocument> printDoc;
printDoc = mDocument;
// Get the webshell for this documentviewer
webContainer = do_QueryInterface(mContainer);
if(webContainer) {
@ -1588,15 +2314,24 @@ PRInt32 width,height;
mPrintDC->GetDeviceSurfaceDimensions(width,height);
// XXX - Hack Alert
// OK, so ther eis a selection, we will print the entire selection
// on one page and then crop the page.
// This means you can never print any selection that is longer than one page
// put it keeps it from page breaking in the middle of your print of the selection
if (IsThereASelection()) {
height = 0x0FFFFFFF;
}
mPrintPC->Init(mPrintDC);
mPrintPC->SetContainer(webContainer);
CreateStyleSet(mDocument,&mPrintSS);
CreateStyleSet(printDoc,&mPrintSS);
rv = NS_NewPresShell(&mPrintPS);
if(NS_FAILED(rv)){
return rv;
}
rv = nsComponentManager::CreateInstance(kViewManagerCID, nsnull, NS_GET_IID(nsIViewManager),(void**)&mPrintVM);
if(NS_FAILED(rv)) {
return rv;
@ -1611,7 +2346,7 @@ PRInt32 width,height;
if(NS_FAILED(rv)) {
return rv;
}
nsRect tbounds = nsRect(0,0,width,height);
rv = mPrintView->Init(mPrintVM,tbounds,nsnull);
if(NS_FAILED(rv)) {
@ -1620,7 +2355,7 @@ PRInt32 width,height;
// setup hierarchical relationship in view manager
mPrintVM->SetRootView(mPrintView);
mPrintPS->Init(mDocument,mPrintPC,mPrintVM,mPrintSS);
mPrintPS->Init(printDoc,mPrintPC,mPrintVM,mPrintSS);
nsCOMPtr<nsIImageGroup> imageGroup;
mPrintPC->GetImageGroup(getter_AddRefs(imageGroup));

View File

@ -123,6 +123,7 @@ nsPresContext::nsPresContext()
mDefaultBackgroundImageOffsetX = mDefaultBackgroundImageOffsetY = 0;
mDefaultDirection = NS_STYLE_DIRECTION_LTR;
mLanguageSpecificTransformType = eLanguageSpecificTransformType_Unknown;
mIsRenderingOnlySelection = PR_FALSE;
}
nsPresContext::~nsPresContext()
@ -1313,6 +1314,15 @@ nsPresContext::GetLanguageSpecificTransformType(
return NS_OK;
}
NS_IMETHODIMP
nsPresContext::IsRenderingOnlySelection(PRBool* aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = mIsRenderingOnlySelection;
return NS_OK;
}
#ifdef MOZ_REFLOW_PERF
NS_IMETHODIMP
nsPresContext::CountReflows(const char * aName, PRUint32 aType)

View File

@ -150,6 +150,9 @@ public:
NS_IMETHOD GetLanguageSpecificTransformType(
nsLanguageSpecificTransformType* aType);
NS_IMETHOD SetIsRenderingOnlySelection(PRBool aVal) { mIsRenderingOnlySelection = aVal; return NS_OK; }
NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult);
#ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType);
#endif
@ -205,7 +208,7 @@ protected:
PRPackedBool mStopped; // loading stopped
PRPackedBool mStopChrome; // should we stop chrome?
PRUint8 mDefaultDirection;
PRPackedBool mIsRenderingOnlySelection;
#ifdef DEBUG
PRBool mInitialized;
#endif

View File

@ -2473,6 +2473,10 @@ nsComboboxControlFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
#ifdef NOISY
printf("%p paint layer %d at (%d, %d, %d, %d)\n", this, aWhichLayer,
aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);

View File

@ -156,10 +156,9 @@ nsFieldSetFrame::Paint(nsIPresContext* aPresContext,
{
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
// Paint our background and border
const nsStyleDisplay* disp =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->IsVisible() && mRect.width && mRect.height) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) &&
isVisible && mRect.width && mRect.height) {
PRIntn skipSides = GetSkipSides();
const nsStyleColor* color =
(const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);

View File

@ -269,7 +269,8 @@ nsFileControlFrame::MouseClick(nsIDOMEvent* aMouseEvent)
// Get Loc title
nsString title;
nsFormControlHelper::GetLocalizedString("FileUpload", title);
nsFormControlHelper::GetLocalizedString(nsFormControlHelper::GetHTMLPropertiesFileName(),
"FileUpload", title);
nsCOMPtr<nsIFilePicker> filePicker = do_CreateInstance("@mozilla.org/filepicker;1");
if (!filePicker)
@ -658,6 +659,10 @@ nsFileControlFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}

View File

@ -402,6 +402,10 @@ nsFormControlFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
nsresult rv = nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect,
aWhichLayer);

View File

@ -872,12 +872,10 @@ nsFormControlHelper::GetInputElementValue(nsIContent* aContent, nsString* aText,
}
//----------------------------------------------------------------------------------
#define form_properties "chrome://communicator/locale/layout/HtmlForm.properties"
// Return localised string for resource string (e.g. "Submit" -> "Submit Query")
// This code is derived from nsBookmarksService::Init() and cookie_Localize()
nsresult
nsFormControlHelper::GetLocalizedString(char* aKey, nsString& oVal)
nsFormControlHelper::GetLocalizedString(const char * aPropFileName, const char* aKey, nsString& oVal)
{
nsresult rv;
nsCOMPtr<nsIStringBundle> bundle;
@ -887,7 +885,7 @@ nsFormControlHelper::GetLocalizedString(char* aKey, nsString& oVal)
NS_WITH_SERVICE(nsIIOService, pNetService, kIOServiceCID, &rv);
if (NS_SUCCEEDED(rv) && pNetService) {
nsCOMPtr<nsIURI> uri;
rv = pNetService->NewURI(form_properties, nsnull, getter_AddRefs(uri));
rv = pNetService->NewURI(aPropFileName, nsnull, getter_AddRefs(uri));
if (NS_SUCCEEDED(rv) && uri) {
// Create bundle

View File

@ -44,6 +44,10 @@ class nsFormFrame;
#define NS_STRING_TRUE NS_LITERAL_STRING("1")
#define NS_STRING_FALSE NS_LITERAL_STRING("0")
// for localization
#define FORM_PROPERTIES "chrome://communicator/locale/layout/HtmlForm.properties"
/**
* Enumeration of possible mouse states used to detect mouse clicks
*/
@ -174,7 +178,8 @@ public:
static nsresult GetWrapPropertyEnum(nsIContent * aContent, nsHTMLTextWrap& aWrapProp);
// Localization Helper
static nsresult GetLocalizedString(char* aKey, nsString& oVal);
static nsresult GetLocalizedString(const char * aPropFileName, const char* aKey, nsString& oVal);
static const char * GetHTMLPropertiesFileName() { return FORM_PROPERTIES; }
static nsresult GetDisabled(nsIContent* aContent, PRBool* oIsDisabled);
//

View File

@ -475,17 +475,18 @@ nsGfxButtonControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
NS_IMETHODIMP
nsGfxButtonControlFrame::GetDefaultLabel(nsString& aString)
{
const char * propname = nsFormControlHelper::GetHTMLPropertiesFileName();
nsresult rv = NS_OK;
PRInt32 type;
GetType(&type);
if (IsReset(type)) {
rv = nsFormControlHelper::GetLocalizedString("Reset", aString);
rv = nsFormControlHelper::GetLocalizedString(propname, "Reset", aString);
}
else if (IsSubmit(type)) {
rv = nsFormControlHelper::GetLocalizedString("Submit", aString);
rv = nsFormControlHelper::GetLocalizedString(propname, "Submit", aString);
}
else if (IsBrowse(type)) {
rv = nsFormControlHelper::GetLocalizedString("Browse", aString);
rv = nsFormControlHelper::GetLocalizedString(propname, "Browse", aString);
}
else {
aString.AssignWithConversion(" ");

View File

@ -367,10 +367,10 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisible())
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
// Paint the background
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);

View File

@ -314,11 +314,10 @@ nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisible())
return NS_OK;
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
// Paint the background
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);

View File

@ -475,14 +475,14 @@ nsHTMLButtonControlFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->IsVisible())
{
nsRect rect(0, 0, mRect.width, mRect.height);
mRenderer.PaintButton(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, rect);
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
nsRect rect(0, 0, mRect.width, mRect.height);
mRenderer.PaintButton(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, rect);
#if 0 // old way
PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
@ -498,10 +498,6 @@ nsHTMLButtonControlFrame::Paint(nsIPresContext* aPresContext,
border.SizeTo(0, 0, 0, 0);
spacing->CalcBorderFor(this, border);
nsRect rect;
GetRect(rect);
rect.x = 0;
rect.y = 0;
rect.Deflate(border);
aRenderingContext.PushState();
PRBool clipEmpty;

View File

@ -99,6 +99,19 @@ nsIsIndexFrame::~nsIsIndexFrame()
}
}
NS_IMETHODIMP
nsIsIndexFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
NS_IMETHODIMP
nsIsIndexFrame::UpdatePromptLabel()
{
@ -125,7 +138,8 @@ nsIsIndexFrame::UpdatePromptLabel()
// We can't make any assumption as to what the default would be
// because the value is localized for non-english platforms, thus
// it might not be the string "This is a searchable index. Enter search keywords: "
result = nsFormControlHelper::GetLocalizedString("IsIndexPrompt", prompt);
result = nsFormControlHelper::GetLocalizedString(nsFormControlHelper::GetHTMLPropertiesFileName(),
"IsIndexPrompt", prompt);
}
nsCOMPtr<nsITextContent> text = do_QueryInterface(mTextContent);
result = text->SetText(prompt.GetUnicode(), prompt.Length(), PR_TRUE);

View File

@ -52,6 +52,11 @@ public:
nsIsIndexFrame();
virtual ~nsIsIndexFrame();
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
// XXX Hack so we can squirrel away the pres context pointer for the KeyPress method
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,

View File

@ -104,6 +104,19 @@ nsLegendFrame::Reflow(nsIPresContext* aPresContext,
}
NS_IMETHODIMP
nsLegendFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
PRInt32 nsLegendFrame::GetAlign()
{
PRInt32 intValue = NS_STYLE_TEXT_ALIGN_LEFT;

View File

@ -52,6 +52,11 @@ public:
NS_IMETHOD Destroy(nsIPresContext *aPresContext);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
#ifdef NS_DEBUG
NS_IMETHOD GetFrameName(nsString& aResult) const;
#endif

View File

@ -287,9 +287,55 @@ nsListControlFrame::Destroy(nsIPresContext *aPresContext)
return nsScrollFrame::Destroy(aPresContext);
}
//---------------------------------------------------------
//NS_IMPL_ADDREF(nsListControlFrame)
//NS_IMPL_RELEASE(nsListControlFrame)
NS_IMETHODIMP
nsListControlFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
nsIStyleContext* sc = mStyleContext;
const nsStyleDisplay* disp = (const nsStyleDisplay*)sc->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisible()) {
return PR_FALSE;
}
// Start by assuming we are visible and need to be painted
PRBool isVisible = PR_TRUE;
PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated);
if (isPaginated) {
PRBool isRendingSelection;;
aPresContext->IsRenderingOnlySelection(&isRendingSelection);
if (isRendingSelection) {
// Check the quick way first
PRBool isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
// if we aren't selected in the mState we could be a container
// so check to see if we are in the selection range
if (!isSelected) {
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
nsCOMPtr<nsISelectionController> selcon;
selcon = do_QueryInterface(shell);
if (selcon) {
nsCOMPtr<nsISelection> selection;
selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mContent));
selection->ContainsNode(node, PR_TRUE, &isVisible);
} else {
isVisible = PR_FALSE;
}
}
}
}
if (isVisible) {
return nsScrollFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
return NS_OK;
}
//---------------------------------------------------------
// Frames are not refcounted, no need to AddRef

View File

@ -193,6 +193,11 @@ public:
NS_IMETHOD MoveTo(nsIPresContext* aPresContext, nscoord aX, nscoord aY);
NS_IMETHOD Destroy(nsIPresContext *aPresContext);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
// nsIFormControlFrame
NS_IMETHOD GetType(PRInt32* aType) const;
NS_IMETHOD GetName(nsString* aName);

View File

@ -6245,6 +6245,19 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext,
}
#endif
// Check to see if we are an absolutely positioned block (div)
// then then check to see if we need to paint.
const nsStylePosition* postionStyle = (const nsStylePosition*)
mStyleContext->GetStyleData(eStyleStruct_Position);
if (NS_STYLE_POSITION_RELATIVE == postionStyle->mPosition ||
NS_STYLE_POSITION_ABSOLUTE == postionStyle->mPosition ||
NS_STYLE_POSITION_FIXED == postionStyle->mPosition) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
}
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);

View File

@ -6245,6 +6245,19 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext,
}
#endif
// Check to see if we are an absolutely positioned block (div)
// then then check to see if we need to paint.
const nsStylePosition* postionStyle = (const nsStylePosition*)
mStyleContext->GetStyleData(eStyleStruct_Position);
if (NS_STYLE_POSITION_RELATIVE == postionStyle->mPosition ||
NS_STYLE_POSITION_ABSOLUTE == postionStyle->mPosition ||
NS_STYLE_POSITION_FIXED == postionStyle->mPosition) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
}
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);

View File

@ -6245,6 +6245,19 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext,
}
#endif
// Check to see if we are an absolutely positioned block (div)
// then then check to see if we need to paint.
const nsStylePosition* postionStyle = (const nsStylePosition*)
mStyleContext->GetStyleData(eStyleStruct_Position);
if (NS_STYLE_POSITION_RELATIVE == postionStyle->mPosition ||
NS_STYLE_POSITION_ABSOLUTE == postionStyle->mPosition ||
NS_STYLE_POSITION_FIXED == postionStyle->mPosition) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
}
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);

View File

@ -107,6 +107,7 @@ nsBulletFrame::GetFrameType(nsIAtom** aType) const
return NS_OK;
}
#include "nsIDOMNode.h"
NS_IMETHODIMP
nsBulletFrame::Paint(nsIPresContext* aCX,
nsIRenderingContext& aRenderingContext,
@ -117,10 +118,8 @@ nsBulletFrame::Paint(nsIPresContext* aCX,
return NS_OK;
}
const nsStyleDisplay* disp =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->IsVisible()) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aCX, aRenderingContext, PR_TRUE, &isVisible)) && isVisible) {
const nsStyleList* myList =
(const nsStyleList*)mStyleContext->GetStyleData(eStyleStruct_List);
PRUint8 listStyleType = myList->mListStyleType;

View File

@ -2308,6 +2308,58 @@ nsFrame::ParentDisablesSelection() const
return PR_FALSE;
}
NS_IMETHODIMP
nsFrame::IsVisibleForPainting(nsIPresContext * aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aCheckVis,
PRBool* aIsVisible)
{
// first check to see if we are visible
if (aCheckVis) {
nsIStyleContext* sc = mStyleContext;
const nsStyleDisplay* disp = (const nsStyleDisplay*)sc->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisible()) {
*aIsVisible = PR_FALSE;
return NS_OK;
}
}
// Start by assuming we are visible and need to be painted
PRBool isVisible = PR_TRUE;
// start by checking to see if we are paginated which probably means
// we are in print preview or printing
PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated);
if (isPaginated) {
// now see if we are rendering selection only
PRBool isRendingSelection;
aPresContext->IsRenderingOnlySelection(&isRendingSelection);
if (isRendingSelection) {
// Check the quick way first (typically only leaf nodes)
PRBool isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
// if we aren't selected in the mState,
// we could be a container so check to see if we are in the selection range
// this is a expensive
if (!isSelected) {
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
nsCOMPtr<nsISelectionController> selcon(do_QueryInterface(shell));
if (selcon) {
nsCOMPtr<nsISelection> selection;
selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mContent));
selection->ContainsNode(node, PR_TRUE, &isVisible);
} else {
isVisible = PR_FALSE;
}
}
}
}
*aIsVisible = isVisible;
return NS_OK;
}
NS_IMETHODIMP

View File

@ -278,6 +278,12 @@ public:
nsIFrame** aProviderFrame,
nsContextProviderRelationship& aRelationship);
// Check Style Visibility and mState for Selection (when printing)
NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aCheckVis,
PRBool* aIsVisible);
// nsIHTMLReflow
NS_IMETHOD WillReflow(nsIPresContext* aPresContext);
NS_IMETHOD Reflow(nsIPresContext* aPresContext,

View File

@ -20,7 +20,7 @@
* Contributor(s):
*/
#include "nsHTMLParts.h"
#include "nsContainerFrame.h"
#include "nsHTMLContainerFrame.h"
#include "nsCSSRendering.h"
#include "nsIDocument.h"
#include "nsIReflowCommand.h"

View File

@ -1092,6 +1092,19 @@ public:
nsIFrame** aProviderFrame,
nsContextProviderRelationship& aRelationship) = 0;
/**
* Determines whether a frame is visible for painting
* this takes into acount whether it is painting selection for printin
* @param aPresContext PresContext
* @param aRenderingContext PresContext
* @param aCheckVis indicates whether it should check for CSS visibility,
* PR_FALSE skips the check, PR_TRUE does the check
* @param aIsVisible return value
*/
NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aCheckVis,
PRBool* aIsVisible) = 0;
private:
NS_IMETHOD_(nsrefcnt) AddRef(void) = 0;
NS_IMETHOD_(nsrefcnt) Release(void) = 0;

View File

@ -26,6 +26,7 @@
#include "nsISupports.h"
class nsIPresContext;
class nsIPrintOptions;
// IID for the nsIPageSequenceFrame interface
// a6cf90d2-15b3-11d2-932e-00805f8add32
@ -91,27 +92,6 @@ public:
//----------------------------------------------------------------------
enum nsPrintRange {
ePrintRange_AllPages, // print all pages
ePrintRange_SpecifiedRange // only print pages in the specified range
};
/**
* Structure containing options for printing.
*/
struct nsPrintOptions {
nsPrintRange range;
PRInt32 startPage, endPage; // only used for ePrintRange_SpecifiedRange
PRPackedBool oddNumberedPages; // print the odd-numbered pages
PRPackedBool evenNumberedPages; // print the even-numbered pages
nsPrintOptions() {
range = ePrintRange_AllPages;
startPage = endPage = 1;
oddNumberedPages = evenNumberedPages = PR_TRUE;
}
};
/**
* Interface for accessing special capabilities of the page sequence frame.
*
@ -136,7 +116,7 @@ public:
* @see nsIPrintStatusCallback#OnProgress()
*/
NS_IMETHOD Print(nsIPresContext* aPresContext,
const nsPrintOptions& aPrintOptions,
nsIPrintOptions* aPrintOptions,
nsIPrintStatusCallback* aStatusCallback) = 0;
private:

View File

@ -590,9 +590,9 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->IsVisible() && mRect.width && mRect.height) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) &&
isVisible && mRect.width && mRect.height) {
// First paint background and borders
nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect,
aWhichLayer);

View File

@ -40,6 +40,12 @@ nsLeafFrame::Paint(nsIPresContext* aPresContext,
nsFramePaintLayer aWhichLayer)
{
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) &&
!isVisible) {// just checks selection painting
return NS_OK; // not visibility
}
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->IsVisibleOrCollapsed()) {

View File

@ -31,6 +31,27 @@
#include "nsLayoutAtoms.h"
#include "nsIStyleSet.h"
#include "nsIPresShell.h"
#include "nsIDeviceContext.h"
// for page number localization formatting
#include "nsTextFormatter.h"
// DateTime Includes
#include "nsDateTimeFormatCID.h"
#include "nsIDateTimeFormat.h"
#include "nsIServiceManager.h"
#include "nsILocale.h"
#include "nsLocaleCID.h"
#include "nsILocaleService.h"
static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID);
static NS_DEFINE_CID(kLocaleServiceCID, NS_LOCALESERVICE_CID);
// Temporary
#include "nsIFontMetrics.h"
// tstaic data members
PRUnichar * nsPageFrame::mPageNumFormat = nsnull;
nsresult
NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
@ -47,10 +68,22 @@ NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
return NS_OK;
}
nsPageFrame::nsPageFrame()
nsPageFrame::nsPageFrame() :
mHeadFootFont(nsnull)
{
}
nsPageFrame::~nsPageFrame()
{
if (mHeadFootFont)
delete mHeadFootFont;
if (mPageNumFormat) {
nsMemory::Free(mPageNumFormat);
mPageNumFormat = nsnull;
}
}
NS_METHOD nsPageFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
@ -173,3 +206,253 @@ nsPageFrame::IsPercentageBase(PRBool& aBase) const
aBase = PR_TRUE;
return NS_OK;
}
//------------------------------------------------------------------------------
nscoord nsPageFrame::GetXPosition(nsIRenderingContext& aRenderingContext,
const nsRect& aRect,
PRInt32 aJust,
const nsString& aStr)
{
PRInt32 width;
aRenderingContext.GetWidth(aStr, width);
nscoord x = aRect.x;
switch (aJust) {
case NS_PRINT_JUSTIFY_LEFT:
// do nothing, already set
break;
case NS_PRINT_JUSTIFY_CENTER:
x += (aRect.width - width) / 2;
break;
case NS_PRINT_JUSTIFY_RIGHT:
x += aRect.width - width;
break;
} // switch
return x;
}
//------------------------------------------------------------------------------
// Draw a Header or footer text lrft,right or center justified
// @parm aRenderingContext - rendering content ot draw into
// @parm aHeaderFooter - indicates whether it is a header or footer
// @parm aJust - indicates the justification of the text
// @parm aStr - The string to be drawn
// @parm aRect - the rect of the page
// @parm aHeight - the height of the text
// @parm aUseHalfThePage - indicates whether the text should limited to the width
// of the entire page or just half the page
void
nsPageFrame::DrawHeaderFooter(nsIRenderingContext& aRenderingContext,
nsIFrame * aFrame,
nsHeaderFooterEnum aHeaderFooter,
PRInt32 aJust,
const nsString& aStr,
const nsRect& aRect,
nscoord aHeight,
PRBool aUseHalfThePage)
{
// first make sure we have a vaild string and that the height of the
// text will fit in the margin
if (aStr.Length() > 0 &&
((aHeaderFooter == eHeader && aHeight < mMargin.top) ||
(aHeaderFooter == eFooter && aHeight < mMargin.bottom))) {
// measure the width of the text
nsString str = aStr;
PRInt32 width;
aRenderingContext.GetWidth(str, width);
PRBool addEllipse = PR_FALSE;
nscoord halfWidth = aRect.width;
if (aUseHalfThePage) {
halfWidth /= 2;
}
// trim the text and add the elipses if it won't fit
while (width >= halfWidth && str.Length() > 1) {
str.SetLength(str.Length()-1);
aRenderingContext.GetWidth(str, width);
addEllipse = PR_TRUE;
}
if (addEllipse && str.Length() > 3) {
str.SetLength(str.Length()-3);
str.AppendWithConversion("...");
aRenderingContext.GetWidth(str, width);
}
// cacl the x and y positions of the text
nsRect rect(aRect);
nscoord x = GetXPosition(aRenderingContext, rect, aJust, str);
nscoord y;
if (aHeaderFooter == eHeader) {
nscoord offset = ((mMargin.top - aHeight) / 2);
y = rect.y - offset - aHeight;
rect.Inflate(0, offset + aHeight);
} else {
nscoord offset = ((mMargin.bottom - aHeight) / 2);
y = rect.y + rect.height + offset;
rect.height += offset + aHeight;
}
// set up new clip and draw the text
PRBool clipEmpty;
aRenderingContext.PushState();
aRenderingContext.SetClipRect(rect, nsClipCombine_kReplace, clipEmpty);
aRenderingContext.DrawString(str, x, y);
aRenderingContext.PopState(clipEmpty);
}
}
//------------------------------------------------------------------------------
NS_IMETHODIMP
nsPageFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
nsresult rv = nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// get the current margin
mPrintOptions->GetMargin(mMargin);
nsRect rect(0,0,mRect.width, mRect.height);
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
// XXX Paint a one-pixel border around the page so it's easy to see where
// each page begins and ends when we're
float p2t;
aPresContext->GetPixelsToTwips(&p2t);
rect.Deflate(NSToCoordRound(p2t), NSToCoordRound(p2t));
aRenderingContext.SetColor(NS_RGB(0, 0, 0));
//aRenderingContext.DrawRect(rect);
rect.Inflate(NSToCoordRound(p2t), NSToCoordRound(p2t));
printf("SPSF::PaintChild -> Painting Frame %p Page No: %d\n", this, mPageNum);
#endif
// use the whole page
rect.width += mMargin.left + mMargin.right;
rect.x -= mMargin.left;
aRenderingContext.SetFont(*mHeadFootFont);
aRenderingContext.SetColor(NS_RGB(0,0,0));
// Get the FontMetrics to determine width.height of strings
nsCOMPtr<nsIDeviceContext> deviceContext;
aPresContext->GetDeviceContext(getter_AddRefs(deviceContext));
NS_ASSERTION(deviceContext, "Couldn't get the device context");
nsCOMPtr<nsIFontMetrics> fontMet;
deviceContext->GetMetricsFor(*mHeadFootFont, *getter_AddRefs(fontMet));
nscoord visibleHeight = 0;
if (fontMet) {
fontMet->GetHeight(visibleHeight);
}
// get the print options bits so we can figure out all the
// the extra pieces of text that need to be drawn
PRInt32 printOptBits;
mPrintOptions->GetPrintOptionsBits(&printOptBits);
// print page numbers
if (printOptBits & NS_PRINT_OPTIONS_PRINT_PAGE_NUMS && mPageNumFormat != nsnull) {
PRInt32 justify = NS_PRINT_JUSTIFY_LEFT;
mPrintOptions->GetPageNumJust(&justify);
PRUnichar * valStr;
// print page number totals "x of x"
if (printOptBits & NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL) {
valStr = nsTextFormatter::smprintf(mPageNumFormat, mPageNum, mTotNumPages);
} else {
valStr = nsTextFormatter::smprintf(mPageNumFormat, mPageNum);
}
nsAutoString pageNoStr(valStr);
nsMemory::Free(valStr);
DrawHeaderFooter(aRenderingContext, this, eFooter, justify, pageNoStr, rect, visibleHeight);
}
// print localized date
if (printOptBits & NS_PRINT_OPTIONS_PRINT_DATE_PRINTED) {
// Get Locale for Formating DateTime
nsCOMPtr<nsILocale> locale;
NS_WITH_SERVICE(nsILocaleService, localeSvc, kLocaleServiceCID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = localeSvc->GetApplicationLocale(getter_AddRefs(locale));
if (NS_SUCCEEDED(rv) && locale) {
nsCOMPtr<nsIDateTimeFormat> dateTime;
rv = nsComponentManager::CreateInstance(kDateTimeFormatCID,
NULL,
NS_GET_IID(nsIDateTimeFormat),
(void**) getter_AddRefs(dateTime));
if (NS_SUCCEEDED(rv)) {
nsAutoString dateString;
time_t ltime;
time( &ltime );
rv = dateTime->FormatTMTime(locale, kDateFormatShort, kTimeFormatNoSeconds, localtime( &ltime ), dateString);
if (NS_SUCCEEDED(rv)) {
DrawHeaderFooter(aRenderingContext, this, eFooter, NS_PRINT_JUSTIFY_RIGHT, dateString, rect, visibleHeight);
}
}
}
}
}
PRBool usingHalfThePage = (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_TITLE) && (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_LOCATION);
// print document title
PRUnichar * title;
mPrintOptions->GetTitle(&title); // creates memory
if (title != nsnull && (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_TITLE)) {
DrawHeaderFooter(aRenderingContext, this, eHeader, NS_PRINT_JUSTIFY_LEFT, nsAutoString(title), rect, visibleHeight, usingHalfThePage);
nsMemory::Free(title);
}
// print document URL
PRUnichar * url;
mPrintOptions->GetURL(&url);
if (title != url && (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_LOCATION)) {
DrawHeaderFooter(aRenderingContext, this, eHeader, NS_PRINT_JUSTIFY_RIGHT, nsAutoString(url), rect, visibleHeight, usingHalfThePage);
nsMemory::Free(url);
}
}
return rv;
}
//------------------------------------------------------------------------------
void
nsPageFrame::SetPrintOptions(nsIPrintOptions * aPrintOptions)
{
NS_ASSERTION(aPrintOptions != nsnull, "Print Options can not be null!");
mPrintOptions = aPrintOptions;
// create a default font
mHeadFootFont = new nsFont("serif", NS_FONT_STYLE_NORMAL,NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL,0,NSIntPointsToTwips(10));
// now get the default font form the print options
mPrintOptions->GetDefaultFont(*mHeadFootFont);
}
//------------------------------------------------------------------------------
void
nsPageFrame::SetPageNumInfo(PRInt32 aPageNumber, PRInt32 aTotalPages)
{
mPageNum = aPageNumber;
mTotNumPages = aTotalPages;
}
//------------------------------------------------------------------------------
void
nsPageFrame::SetPageNumberFormat(PRUnichar * aFormatStr)
{
NS_ASSERTION(aFormatStr != nsnull, "Format string cannot be null!");
if (mPageNumFormat != nsnull) {
nsMemory::Free(mPageNumFormat);
}
mPageNumFormat = aFormatStr;
}

View File

@ -22,17 +22,25 @@
#ifndef nsPageFrame_h___
#define nsPageFrame_h___
#include "nsHTMLContainerFrame.h"
#include "nsContainerFrame.h"
#include "nsIPrintOptions.h"
// Page frame class used by the simple page sequence frame
class nsPageFrame : public nsContainerFrame {
public:
friend nsresult NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
// nsIFrame
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aMaxSize,
nsReflowStatus& aStatus);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
NS_IMETHOD IsPercentageBase(PRBool& aBase) const;
/**
@ -47,8 +55,51 @@ public:
NS_IMETHOD GetFrameName(nsString& aResult) const;
#endif
//////////////////
// For Printing
//////////////////
// Set the print options object into the page for printing
virtual void SetPrintOptions(nsIPrintOptions * aPrintOptions);
// Tell the page which page number it is out of how many
virtual void SetPageNumInfo(PRInt32 aPageNumber, PRInt32 aTotalPages);
// This is class is now responsible for freeing the memory
static void SetPageNumberFormat(PRUnichar * aFormatStr);
protected:
nsPageFrame();
virtual ~nsPageFrame();
typedef enum {
eHeader,
eFooter
} nsHeaderFooterEnum;
nscoord GetXPosition(nsIRenderingContext& aRenderingContext,
const nsRect& aRect,
PRInt32 aJust,
const nsString& aStr);
void DrawHeaderFooter(nsIRenderingContext& aRenderingContext,
nsIFrame * aFrame,
nsHeaderFooterEnum aHeaderFooter,
PRInt32 aJust,
const nsString& sStr,
const nsRect& aRect,
nscoord aHeight,
PRBool aUseHalfThePage = PR_TRUE);
nsCOMPtr<nsIPrintOptions> mPrintOptions;
PRInt32 mPageNum;
PRInt32 mTotNumPages;
nsMargin mMargin;
nsFont * mHeadFootFont;
static PRUnichar * mPageNumFormat;
};
#endif /* nsPageFrame_h___ */

View File

@ -31,6 +31,24 @@
#include "nsIViewManager.h"
#include "nsIPresShell.h"
#include "nsIStyleSet.h"
#include "nsIFontMetrics.h"
#include "nsIPrintOptions.h"
#include "nsPageFrame.h"
#define OFFSET_NOT_SET -1
// This is for localization of the "x of n" pages string
// this class contains a helper method we need to get
// a string from a string bundle
#include "nsFormControlHelper.h"
#define PRINTING_PROPERTIES "chrome://communicator/locale/printing.properties"
// Print Options
#include "nsIPrintOptions.h"
#include "nsGfxCIID.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID);
//
nsresult
NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
@ -47,7 +65,28 @@ NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
return NS_OK;
}
nsSimplePageSequenceFrame::nsSimplePageSequenceFrame()
nsSimplePageSequenceFrame::nsSimplePageSequenceFrame() :
mIsPrintingSelection(PR_FALSE)
{
mStartOffset = OFFSET_NOT_SET;
mEndOffset = OFFSET_NOT_SET;
nscoord halfInch = NS_INCHES_TO_TWIPS(0.5);
mMargin.SizeTo(halfInch, halfInch, halfInch, halfInch);
// XXX this code and the object data member "mIsPrintingSelection" is only needed
// for the hack for printing selection where we make the page the max size
nsresult rv;
NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv);
if (NS_SUCCEEDED(rv) && printService) {
PRInt32 printType;
printService->GetPrintRange(&printType);
mIsPrintingSelection = ePrintRange_Selection == nsPrintRange(printType);
}
}
nsSimplePageSequenceFrame::~nsSimplePageSequenceFrame()
{
}
@ -67,9 +106,6 @@ nsSimplePageSequenceFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr
//----------------------------------------------------------------------
// XXX Hack
#define PAGE_SPACING_TWIPS 100
// Creates a continuing page frame
nsresult
nsSimplePageSequenceFrame::CreateContinuingPageFrame(nsIPresContext* aPresContext,
@ -110,12 +146,10 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext* aPresConte
aReflowState.reflowCommand->GetNext(nextFrame);
// Compute the y-offset of this page
for (nsIFrame* f = mFrames.FirstChild(); f != nextFrame;
f->GetNextSibling(&f)) {
for (nsIFrame* f = mFrames.FirstChild(); f != nextFrame; f->GetNextSibling(&f)) {
nsSize size;
f->GetSize(size);
aY += size.height + PAGE_SPACING_TWIPS;
aY += size.height + mMargin.top + mMargin.bottom;
}
// Reflow the page
@ -131,7 +165,7 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext* aPresConte
// Place and size the page. If the page is narrower than our max width, then
// center it horizontally
FinishReflowChild(nextFrame, aPresContext, kidSize, aX, aY, 0);
aY += kidSize.height + PAGE_SPACING_TWIPS;
aY += kidSize.height + mMargin.top + mMargin.bottom;
// Check if the page is complete...
nsIFrame* kidNextInFlow;
@ -174,7 +208,7 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext* aPresConte
aY += childSize.height;
// Leave a slight gap between the pages
aY += PAGE_SPACING_TWIPS;
aY += mMargin.top + mMargin.bottom;
// Is the page complete?
kidFrame->GetNextInFlow(&kidNextInFlow);
@ -216,15 +250,21 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext,
nsSize pageSize;
aPresContext->GetPageWidth(&pageSize.width);
aPresContext->GetPageHeight(&pageSize.height);
PRInt32 extra = aReflowState.availableWidth - 2 * PAGE_SPACING_TWIPS - pageSize.width;
nscoord x = PAGE_SPACING_TWIPS;
if (extra > 0) {
x += extra / 2;
// XXX - Hack Alert
// OK, so ther eis a selection, we will print the entire selection
// on one page and then crop the page.
// This means you can never print any selection that is longer than one page
// put it keeps it from page breaking in the middle of your print of the selection
// (see also nsDocumentViewer.cpp)
if (mIsPrintingSelection) {
pageSize.height = 0x0FFFFFFF;
}
nscoord x = mMargin.left;
// Running y-offset for each page
nscoord y = PAGE_SPACING_TWIPS;
nscoord y = mMargin.top;
// See if it's an incremental reflow command
if (eReflowReason_Incremental == aReflowState.reason) {
@ -240,6 +280,10 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
pageSize, reflowReason);
nsReflowStatus status;
kidReflowState.availableWidth = pageSize.width - mMargin.left - mMargin.right;
kidReflowState.availableHeight = pageSize.height - mMargin.top - mMargin.bottom;
kidReflowState.mComputedWidth = kidReflowState.availableWidth;
//kidReflowState.mComputedHeight = kidReflowState.availableHeight;
// Place and size the page. If the page is narrower than our
// max width then center it horizontally
@ -248,8 +292,16 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext,
FinishReflowChild(kidFrame, aPresContext, kidSize, x, y, 0);
y += kidSize.height;
nsIView* view;
kidFrame->GetView(aPresContext, &view);
NS_ASSERTION(nsnull != view, "no page view");
nsRect rect;
kidFrame->GetRect(rect);
nsRect viewRect;
view->GetBounds(viewRect);
// Leave a slight gap between the pages
y += PAGE_SPACING_TWIPS;
y += mMargin.top + mMargin.bottom;
// Is the page complete?
nsIFrame* kidNextInFlow;
@ -274,9 +326,9 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext,
}
// Return our desired size
aDesiredSize.height = y;
aDesiredSize.width = 2*PAGE_SPACING_TWIPS + pageSize.width;
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.height = y;
aDesiredSize.width = pageSize.width;
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
NS_FRAME_TRACE_REFLOW_OUT("nsSimplePageSequeceFrame::Reflow", aStatus);
@ -293,53 +345,6 @@ nsSimplePageSequenceFrame::GetFrameName(nsString& aResult) const
}
#endif
NS_IMETHODIMP
nsSimplePageSequenceFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
// Paint a white background
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,
aWhichLayer);
}
void
nsSimplePageSequenceFrame::PaintChild(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsIFrame* aFrame,
nsFramePaintLayer aWhichLayer)
{
// Let the page paint
nsContainerFrame::PaintChild(aPresContext, aRenderingContext,
aDirtyRect, aFrame, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// 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(&p2t);
aRenderingContext.SetColor(NS_RGB(0, 0, 0));
aFrame->GetRect(pageBounds);
pageBounds.Inflate(NSToCoordRound(p2t), NSToCoordRound(p2t));
// this paints a rectangle around the for the printer output,
// which sometimes appears, other times
// goes away. I have to look into this further or ask troy..
// I took it out for the time being to fix some bugs -- dwc
//aRenderingContext.DrawRect(pageBounds);
}
}
//----------------------------------------------------------------------
// Helper function that sends the progress notification. Returns PR_TRUE
@ -361,15 +366,37 @@ SendStatusNotification(nsIPrintStatusCallback* aStatusCallback,
NS_IMETHODIMP
nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext,
const nsPrintOptions& aPrintOptions,
nsIPrintOptions* aPrintOptions,
nsIPrintStatusCallback* aStatusCallback)
{
NS_ENSURE_ARG_POINTER(aPresContext);
NS_ENSURE_ARG_POINTER(aPrintOptions);
nsPrintRange printRangeType;
PRInt32 fromPageNum;
PRInt32 toPageNum;
PRInt32 marginL, marginR, marginT, marginB;
PRBool printEvenPages, printOddPages;
PRInt32 printType;
aPrintOptions->GetPrintRange(&printType);
printRangeType = (nsPrintRange)printType;
aPrintOptions->GetPageRange(&fromPageNum, &toPageNum);
aPrintOptions->GetMargins(&marginT, &marginL, &marginR, &marginB);
mMargin.SizeTo(nscoord(marginL), nscoord(marginT), nscoord(marginR), nscoord(marginB));
aPrintOptions->GetPrintOptions(NS_PRINT_OPTIONS_PRINT_EVEN_PAGES, &printEvenPages);
aPrintOptions->GetPrintOptions(NS_PRINT_OPTIONS_PRINT_ODD_PAGES, &printOddPages);
PRBool doingPageRange = ePrintRange_SpecifiedPageRange == printRangeType ||
ePrintRange_Selection == printRangeType;
// If printing a range of pages make sure at least the starting page
// number is valid
PRInt32 totalPages = mFrames.GetLength();
if (ePrintRange_SpecifiedRange == aPrintOptions.range) {
if (aPrintOptions.startPage > totalPages) {
if (doingPageRange) {
if (fromPageNum > totalPages) {
return NS_ERROR_INVALID_ARG;
}
}
@ -383,29 +410,158 @@ nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext,
presShell->GetViewManager(getter_AddRefs(vm));
nsresult rv = NS_OK;
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
{
nsIView * seqView;
GetView(aPresContext, &seqView);
nsRect rect;
GetRect(rect);
printf("Seq Frame: - %d,%d,%d,%d ", rect.x, rect.y, rect.width, rect.height);
printf("view: %p ", seqView);
nsRect viewRect;
if (seqView) {
seqView->GetBounds(viewRect);
printf(" %d,%d,%d,%d", viewRect.x, viewRect.y, viewRect.width, viewRect.height);
}
printf("\n");
}
{
PRInt32 pageNum = 1;
for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) {
nsIView* view;
page->GetView(aPresContext, &view);
NS_ASSERTION(nsnull != view, "no page view");
nsRect rect;
page->GetRect(rect);
nsRect viewRect;
view->GetBounds(viewRect);
printf("Page: %d - %d,%d,%d,%d ", pageNum, rect.x, rect.y, rect.width, rect.height);
printf(" %d,%d,%d,%d\n", viewRect.x, viewRect.y, viewRect.width, viewRect.height);
pageNum++;
}
}
printf("***** Setting aPresContext %p is painting selection %d\n", aPresContext, ePrintRange_Selection == printRangeType);
#endif
// Determine if we are rendering only the selection
aPresContext->SetIsRenderingOnlySelection(ePrintRange_Selection == printRangeType);
if (doingPageRange) {
// XXX because of the hack for making the selection all print on one page
// we must make sure that the page is sized correctly before printing.
PRInt32 width,height;
dc->GetDeviceSurfaceDimensions(width,height);
height -= mMargin.top + mMargin.bottom;
PRInt32 pageNum = 1;
nscoord y = mMargin.top;
for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) {
nsIView* view;
page->GetView(aPresContext, &view);
NS_ASSERTION(nsnull != view, "no page view");
if (pageNum < fromPageNum || pageNum > toPageNum) {
// XXX Doesn't seem like we need to do this
// because we ask only the pages we want to print
//view->SetVisibility(nsViewVisibility_kHide);
} else {
nsRect rect;
page->GetRect(rect);
rect.y = y;
rect.height = height;
page->SetRect(aPresContext, rect);
nsRect viewRect;
view->GetBounds(viewRect);
viewRect.y = y;
viewRect.height = height;
view->SetBounds(viewRect);
y += rect.height + mMargin.top + mMargin.bottom;
}
pageNum++;
}
// adjust total number of pages
if (ePrintRange_Selection == printRangeType) {
totalPages = toPageNum - fromPageNum + 1;
} else {
totalPages = pageNum - 1;
}
}
// XXX - This wouldn't have to be done each time
// but it isn't that expensive and this the best place
// to have access to a localized file properties file
//
// Note: because this is done here it makes a little bit harder
// to have UI for setting the header/footer font name and size
//
// Get default font name and size to be used for the headers and footers
nsAutoString fontName;
rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, "fontname", fontName);
if (NS_FAILED(rv)) {
fontName.AssignWithConversion("serif");
}
nsAutoString fontSizeStr;
nscoord pointSize = 10;;
rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, "fontsize", fontSizeStr);
if (NS_SUCCEEDED(rv)) {
PRInt32 errCode;
pointSize = fontSizeStr.ToInteger(&errCode);
if (NS_FAILED(errCode)) {
pointSize = 10;
}
}
aPrintOptions->SetFontNamePointSize(fontName, pointSize);
// Now go get the Localized Page Formating String
PRBool doingPageTotals = PR_TRUE;
aPrintOptions->GetPrintOptions(NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL, &doingPageTotals);
nsAutoString pageFormatStr;
rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES,
doingPageTotals?"pageofpages":"pagenumber",
pageFormatStr);
if (NS_FAILED(rv)) { // back stop formatting
pageFormatStr.AssignWithConversion(doingPageTotals?"%ld of %ld":"%ld");
}
// Sets the format into a static data memeber which will own the memory and free it
nsPageFrame::SetPageNumberFormat(pageFormatStr.ToNewUnicode());
// Print each specified page
PRInt32 pageNum = 1;
// pageNum keeps track of the current page and what pages are printing
//
// printedPageNum keeps track of the current page number to be printed
// Note: When print al the pages or a page range the printed page shows the
// actual page number, when printing selection it prints the page number starting
// with the first page of the selection. For example if the user has a
// selection that starts on page 2 and ends on page 3, the page numbers when
// print are 1 and then two (which is different than printing a page range, where
// the page numbers would have been 2 and then 3)
PRInt32 pageNum = 1;
PRInt32 printedPageNum = 1;
for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) {
// See whether we should print this page
PRBool printThisPage = PR_TRUE;
// 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) {
if (doingPageRange) {
if (pageNum < fromPageNum) {
printThisPage = PR_FALSE;
} else if (pageNum > aPrintOptions.endPage) {
} else if (pageNum > toPageNum) {
break;
}
}
// Check for printing of odd and even pages
if (pageNum & 0x1) {
if (!aPrintOptions.oddNumberedPages) {
if (!printOddPages) {
printThisPage = PR_FALSE; // don't print odd numbered page
}
} else {
if (!aPrintOptions.evenNumberedPages) {
if (!printEvenPages) {
printThisPage = PR_FALSE; // don't print even numbered page
}
}
@ -424,18 +580,37 @@ nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext,
}
break;
}
// cast the frame to be a page frame
nsPageFrame * pf = NS_STATIC_CAST(nsPageFrame*, page);
if (pf != nsnull) {
pf->SetPrintOptions(aPrintOptions);
pf->SetPageNumInfo(printedPageNum, totalPages);
}
// Print the page
nsIView* view;
page->GetView(aPresContext, &view);
NS_ASSERTION(nsnull != view, "no page view");
vm->Display(view);
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
{
char * fontname = fontName.ToNewCString();
printf("SPSF::Paint -> FontName[%s] Point Size: %d\n", fontname, pointSize);
nsMemory::Free(fontname);
printf("SPSF::Paint -> PageNo: %d View: %p\n", pageNum, view);
}
#endif
vm->Display(view, mMargin.left, mMargin.top);
// this view was printed and since display set the origin
// 0,0 there is a danger that this view can be printed again
// If it is a sibling to another page/view. Setting the visibility
// to hide will keep this page from printing again - dwc
view->SetVisibility(nsViewVisibility_kHide);
//
// XXX Doesn't seem like we need to do this anymore
//view->SetVisibility(nsViewVisibility_kHide);
// Finish printing of the page
if (!SendStatusNotification(aStatusCallback, pageNum, totalPages,
@ -452,9 +627,21 @@ nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext,
}
}
// Increment the page number
if (ePrintRange_Selection != printRangeType ||
(ePrintRange_Selection == printRangeType && printThisPage)) {
printedPageNum++;
}
pageNum++;
}
return rv;
}
NS_IMETHODIMP
nsSimplePageSequenceFrame::SetOffsets(nscoord aStartOffset, nscoord aEndOffset)
{
mStartOffset = aStartOffset;
mEndOffset = aEndOffset;
return NS_OK;
}

View File

@ -22,8 +22,9 @@
#ifndef nsSimplePageSequence_h___
#define nsSimplePageSequence_h___
#include "nsHTMLContainerFrame.h"
#include "nsIPageSequenceFrame.h"
#include "nsContainerFrame.h"
#include "nsIPrintOptions.h"
// Simple page sequence frame class. Used when we're in paginated mode
class nsSimplePageSequenceFrame : public nsContainerFrame,
@ -40,16 +41,12 @@ public:
const nsHTMLReflowState& aMaxSize,
nsReflowStatus& aStatus);
// nsIFrame
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
// nsIPageSequenceFrame
NS_IMETHOD Print(nsIPresContext* aPresContext,
const nsPrintOptions& aPrintOptions,
nsIPrintOptions* aPrintOptions,
nsIPrintStatusCallback* aStatusCallback);
NS_IMETHOD SetOffsets(nscoord aStartOffset, nscoord aEndOffset);
NS_IMETHOD SetPageNo(PRInt32 aPageNo) { return NS_OK;}
#ifdef DEBUG
// Debugging
@ -58,11 +55,7 @@ public:
protected:
nsSimplePageSequenceFrame();
virtual void PaintChild(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsIFrame* aFrame,
nsFramePaintLayer aWhichLayer);
virtual ~nsSimplePageSequenceFrame();
nsresult IncrementalReflow(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
@ -73,9 +66,14 @@ protected:
nsresult CreateContinuingPageFrame(nsIPresContext* aPresContext,
nsIFrame* aPageFrame,
nsIFrame** aContinuingFrame);
NS_IMETHOD_(nsrefcnt) AddRef(void) {return nsContainerFrame::AddRef();}
NS_IMETHOD_(nsrefcnt) Release(void) {return nsContainerFrame::Release();}
nscoord mStartOffset;
nscoord mEndOffset;
nsMargin mMargin;
PRBool mIsPrintingSelection;
};
#endif /* nsSimplePageSequence_h___ */

View File

@ -427,6 +427,11 @@ public:
PRInt32* outFrameContentOffset,
nsIFrame* *outChildFrame);
NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aCheckVis,
PRBool* aIsVisible);
// nsIHTMLReflow
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
@ -659,6 +664,19 @@ public:
PRUnichar* aBuffer, PRInt32 aLength,
nscoord aWidth);
PRBool IsTextInSelection(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext);
nsresult GetTextInfoForPainting(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIPresShell** aPresShell,
nsISelectionController** aSelectionController,
PRBool& aDisplayingSelection,
PRBool& aIsPaginated,
PRBool& aIsSelected,
PRInt16& aSelectionValue,
nsILineBreaker** aLineBreaker);
void PaintUnicodeText(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIStyleContext* aStyleContext,
@ -805,6 +823,7 @@ public:
nsTextFrame::TextStyle & CurrentStyle();
nscolor CurrentForeGroundColor();
PRBool CurrentBackGroundColor(nscolor &aColor);
PRBool IsBeforeOrAfter();
private:
union {
PRUnichar *mUniStr;
@ -1042,6 +1061,11 @@ DrawSelectionIterator::CurrentBackGroundColor(nscolor &aColor)
return PR_FALSE;
}
PRBool
DrawSelectionIterator::IsBeforeOrAfter()
{
return mCurrentIdx != (PRUint32)mDetails->mStart;
}
//END DRAWSELECTIONITERATOR!!
@ -1219,9 +1243,8 @@ nsTextFrame::Paint(nsIPresContext* aPresContext,
return NS_OK;
}
nsIStyleContext* sc = mStyleContext;
const nsStyleDisplay* disp = (const nsStyleDisplay*)
sc->GetStyleData(eStyleStruct_Display);
if (disp->IsVisible()) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && isVisible) {
TextStyle ts(aPresContext, aRenderingContext, mStyleContext);
if (ts.mSmallCaps || (0 != ts.mWordSpacing) || (0 != ts.mLetterSpacing)
|| ts.mJustifying) {
@ -1261,6 +1284,7 @@ nsTextFrame::Paint(nsIPresContext* aPresContext,
// Use char rendering routine
PaintAsciiText(aPresContext, aRenderingContext, sc, ts, 0, 0);
}
}
}
return NS_OK;
@ -1735,6 +1759,194 @@ nsTextFrame::GetContentAndOffsetsForSelection(nsIPresContext *aPresContext, nsIC
return NS_OK;
}
//---------------------------------------------------------
nsresult nsTextFrame::GetTextInfoForPainting(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIPresShell** aPresShell,
nsISelectionController** aSelectionController,
PRBool& aDisplayingSelection,
PRBool& aIsPaginated,
PRBool& aIsSelected,
PRInt16& aSelectionValue,
nsILineBreaker** aLineBreaker)
{
NS_ENSURE_ARG_POINTER(aPresContext);
NS_ENSURE_ARG_POINTER(aPresShell);
NS_ENSURE_ARG_POINTER(aSelectionController);
NS_ENSURE_ARG_POINTER(aLineBreaker);
//get the presshell
nsresult rv = aPresContext->GetShell(aPresShell);
if (NS_FAILED(rv) || (*aPresShell) == nsnull)
return NS_ERROR_FAILURE;
//get the selection controller
rv = GetSelectionController(aPresContext, aSelectionController);
if (NS_FAILED(rv) || !(*aSelectionController))
return NS_ERROR_FAILURE;
aPresContext->IsPaginated(&aIsPaginated);
PRBool isRenderingOnlySelection;
aPresContext->IsRenderingOnlySelection(&isRenderingOnlySelection);
(*aSelectionController)->GetDisplaySelection(&aSelectionValue);
//if greater than hidden then we display some kind of selection
aDisplayingSelection = (aSelectionValue > nsISelectionController::SELECTION_HIDDEN) ||
(aIsPaginated && isRenderingOnlySelection);
// Transform text from content into renderable form
// XXX If the text fragment is already Unicode and text text wasn't
// transformed when we formatted it, then there's no need to do all
// this and we should just render the text fragment directly. See
// PaintAsciiText()...
nsCOMPtr<nsIDocument> doc;
(*aPresShell)->GetDocument(getter_AddRefs(doc));
if (!doc)
return NS_ERROR_FAILURE;
doc->GetLineBreaker(aLineBreaker);
nsFrameState frameState;
GetFrameState(&frameState);
aIsSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
return NS_OK;
}
PRBool
nsTextFrame::IsTextInSelection(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext)
{
nsCOMPtr<nsISelectionController> selCon;
nsCOMPtr<nsIPresShell> shell;
PRBool displaySelection;
PRBool isPaginated;
PRBool isSelected;
PRInt16 selectionValue;
nsCOMPtr<nsILineBreaker> lb;
if (NS_FAILED(GetTextInfoForPainting(aPresContext,
aRenderingContext,
getter_AddRefs(shell),
getter_AddRefs(selCon),
displaySelection,
isPaginated,
isSelected,
selectionValue,
getter_AddRefs(lb)))) {
return PR_FALSE;
}
// Make enough space to transform
nsAutoTextBuffer paintBuffer;
nsAutoIndexBuffer indexBuffer;
if (NS_FAILED(indexBuffer.GrowTo(mContentLength + 1))) {
return PR_FALSE;
}
TextStyle ts(aPresContext, aRenderingContext, mStyleContext);
// Transform text from content into renderable form
// XXX If the text fragment is already Unicode and text text wasn't
// transformed when we formatted it, then there's no need to do all
// this and we should just render the text fragment directly. See
// PaintAsciiText()...
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 textLength;
// no need to worry about justification, that's always on the slow path
PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
PRInt32* ip = indexBuffer.mBuffer;
PRUnichar* text = paintBuffer.mBuffer;
if (0 != textLength) {
SelectionDetails *details = nsnull;
nsCOMPtr<nsIFrameSelection> frameSelection;
//get the frameSelection from the selection controller
if (selCon) {
frameSelection = do_QueryInterface(selCon); //this MAY implement
}
nsresult rv = NS_OK;
//if that failed get it from the pres shell
if (!frameSelection)
rv = shell->GetFrameSelection(getter_AddRefs(frameSelection));
if (NS_SUCCEEDED(rv) && frameSelection){
nsCOMPtr<nsIContent> content;
PRInt32 offset;
PRInt32 length;
rv = GetContentAndOffsetsForSelection(aPresContext,getter_AddRefs(content),&offset,&length);
if (NS_SUCCEEDED(rv) && content){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &details, PR_FALSE);
}
}
//where are the selection points "really"
SelectionDetails *sdptr = details;
while (sdptr){
sdptr->mStart = ip[sdptr->mStart] - mContentOffset;
sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset;
sdptr = sdptr->mNext;
}
//while we have substrings...
//PRBool drawn = PR_FALSE;
DrawSelectionIterator iter(details,text,(PRUint32)textLength, ts, nsISelectionController::SELECTION_NORMAL);
if (!iter.IsDone() && iter.First()) {
return PR_TRUE;
}
sdptr = details;
if (details) {
while ((sdptr = details->mNext) != nsnull) {
delete details;
details = sdptr;
}
delete details;
}
}
return PR_FALSE;
}
NS_IMETHODIMP
nsTextFrame::IsVisibleForPainting(nsIPresContext * aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aCheckVis,
PRBool* aIsVisible)
{
if (aCheckVis) {
nsIStyleContext* sc = mStyleContext;
const nsStyleDisplay* disp = (const nsStyleDisplay*)sc->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisible()) {
*aIsVisible = PR_FALSE;
return NS_OK;
}
}
// Start by assuming we are visible and need to be painted
PRBool isVisible = PR_TRUE;
PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated);
if (isPaginated) {
PRBool isRendingSelection;
aPresContext->IsRenderingOnlySelection(&isRendingSelection);
if (isRendingSelection) {
// Check the quick way first
PRBool isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (isSelected) {
isVisible = IsTextInSelection(aPresContext, aRenderingContext);
} else {
isVisible = PR_FALSE;
}
}
}
*aIsVisible = isVisible;
return NS_OK;
}
void
nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
@ -1743,22 +1955,24 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
TextStyle& aTextStyle,
nscoord dx, nscoord dy)
{
nsCOMPtr<nsIPresShell> shell;
//get the presshell
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_FAILED(rv) || !shell)
return;
//get the selection controller
nsCOMPtr<nsISelectionController> selCon;
rv = GetSelectionController(aPresContext, getter_AddRefs(selCon));
if (NS_FAILED(rv) || !selCon)
return;
nsCOMPtr<nsIPresShell> shell;
PRBool displaySelection;
PRBool isPaginated;
PRBool isSelected;
PRInt16 selectionValue;
selCon->GetDisplaySelection(&selectionValue);
//if greater than hidden then we display some kind of selection
PRBool displaySelection = selectionValue > nsISelectionController::SELECTION_HIDDEN;
nsCOMPtr<nsILineBreaker> lb;
if (NS_FAILED(GetTextInfoForPainting(aPresContext,
aRenderingContext,
getter_AddRefs(shell),
getter_AddRefs(selCon),
displaySelection,
isPaginated,
isSelected,
selectionValue,
getter_AddRefs(lb)))) {
return;
}
// Make enough space to transform
nsAutoTextBuffer paintBuffer;
nsAutoIndexBuffer indexBuffer;
@ -1774,12 +1988,7 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
// transformed when we formatted it, then there's no need to do all
// this and we should just render the text fragment directly. See
// PaintAsciiText()...
nsCOMPtr<nsIDocument> doc;
shell->GetDocument(getter_AddRefs(doc));
if (!doc)
return;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 textLength;
// no need to worry about justification, that's always on the slow path
@ -1788,10 +1997,6 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
PRInt32* ip = indexBuffer.mBuffer;
PRUnichar* text = paintBuffer.mBuffer;
nsFrameState frameState;
PRBool isSelected;
GetFrameState(&frameState);
isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (0 != textLength)
{
@ -1808,12 +2013,13 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
{ //we draw according to selection rules
SelectionDetails *details = nsnull;
nsCOMPtr<nsIFrameSelection> frameSelection;
//get the frameSelection from the selection controller
if (NS_SUCCEEDED(rv) && selCon)
//get the frameSelection from the selection controller
if (selCon)
{
frameSelection = do_QueryInterface(selCon); //this MAY implement
}
//if that failed get it from the pres shell
//if that failed get it from the pres shell
nsresult rv = NS_OK;
if (!frameSelection)
rv = shell->GetFrameSelection(getter_AddRefs(frameSelection));
if (NS_SUCCEEDED(rv) && frameSelection){
@ -1853,7 +2059,7 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING
{
if (iter.CurrentBackGroundColor(currentBKColor))
if (iter.CurrentBackGroundColor(currentBKColor) && !isPaginated)
{//DRAW RECT HERE!!!
aRenderingContext.SetColor(currentBKColor);
aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height);
@ -1863,16 +2069,20 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
else
newWidth =0;
aRenderingContext.SetColor(currentFGColor);
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
if (isPaginated && !iter.IsBeforeOrAfter()) {
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
} else if (!isPaginated) {
aRenderingContext.SetColor(currentFGColor);
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
}
currentX+=newWidth;//increment twips X start
iter.Next();
}
}
else
else if (!isPaginated)
{
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
@ -2298,18 +2508,24 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
TextStyle& aTextStyle,
nscoord dx, nscoord dy)
{
nsCOMPtr<nsIPresShell> shell;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_FAILED(rv) || !shell)
return;
nsCOMPtr<nsISelectionController> selCon;
rv = GetSelectionController(aPresContext, getter_AddRefs(selCon));
if (NS_FAILED(rv) || !selCon)
return;
nsCOMPtr<nsIPresShell> shell;
PRBool displaySelection;
PRBool isPaginated;
PRBool isSelected;
PRInt16 selectionValue;
selCon->GetDisplaySelection(&selectionValue);
PRBool displaySelection = selectionValue > nsISelectionController::SELECTION_HIDDEN;
nsCOMPtr<nsILineBreaker> lb;
if (NS_FAILED(GetTextInfoForPainting(aPresContext,
aRenderingContext,
getter_AddRefs(shell),
getter_AddRefs(selCon),
displaySelection,
isPaginated,
isSelected,
selectionValue,
getter_AddRefs(lb)))) {
return;
}
// Make enough space to transform
@ -2321,13 +2537,6 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
nscoord width = mRect.width;
PRInt32 textLength;
// Transform text from content into renderable form
nsCOMPtr<nsIDocument> doc;
shell->GetDocument(getter_AddRefs(doc));
if (!doc)
return;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 numSpaces;
@ -2337,10 +2546,7 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
PRInt32* ip = indexBuffer.mBuffer;
PRUnichar* text = paintBuffer.mBuffer;
nsFrameState frameState;
PRBool isSelected;
GetFrameState(&frameState);
isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (0 != textLength) {
ComputeExtraJustificationSpacing(aRenderingContext, aTextStyle, text, textLength, numSpaces);
if (!displaySelection || !isSelected) {
@ -2355,6 +2561,7 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
SelectionDetails *details = nsnull;
nsCOMPtr<nsIFrameSelection> frameSelection;
//get the frame selection
nsresult rv = NS_OK;
frameSelection = do_QueryInterface(selCon); //this MAY implement
if (!frameSelection)//if that failed get it from the presshell
rv = shell->GetFrameSelection(getter_AddRefs(frameSelection));
@ -2405,16 +2612,23 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
else
newWidth =0;
aRenderingContext.SetColor(currentFGColor);
RenderString(aRenderingContext,aStyleContext, aTextStyle, currenttext,
currentlength, currentX, dy, width, details);
//increment twips X start but remember to get ready for next draw by reducing current x by letter spacing amount
if (isPaginated && !iter.IsBeforeOrAfter()) {
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
RenderString(aRenderingContext,aStyleContext, aTextStyle, currenttext,
currentlength, currentX, dy, width, details);
} else if (!isPaginated) {
aRenderingContext.SetColor(currentFGColor);
RenderString(aRenderingContext,aStyleContext, aTextStyle, currenttext,
currentlength, currentX, dy, width, details);
}
//increment twips X start but remember to get ready for next draw by reducing current x by letter spacing amount
currentX+=newWidth;// + aTextStyle.mLetterSpacing;
iter.Next();
}
}
else
else if (!isPaginated)
{
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
RenderString(aRenderingContext,aStyleContext, aTextStyle, text,
@ -2440,21 +2654,25 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
nscoord dx, nscoord dy)
{
NS_PRECONDITION(0 == (TEXT_HAS_MULTIBYTE & mState), "text is multi-byte");
nsCOMPtr<nsIPresShell> shell;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_FAILED(rv) || !shell)
return;
nsCOMPtr<nsISelectionController> selCon;
rv = GetSelectionController(aPresContext, getter_AddRefs(selCon));
if (NS_FAILED(rv) || !selCon)
return;
nsCOMPtr<nsIPresShell> shell;
PRBool displaySelection;
PRBool isPaginated;
PRBool isSelected;
PRInt16 selectionValue;
PRBool isSelected;
selCon->GetDisplaySelection(&selectionValue);
PRBool displaySelection = selectionValue > nsISelectionController::SELECTION_HIDDEN;
isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
nsCOMPtr<nsILineBreaker> lb;
if (NS_FAILED(GetTextInfoForPainting(aPresContext,
aRenderingContext,
getter_AddRefs(shell),
getter_AddRefs(selCon),
displaySelection,
isPaginated,
isSelected,
selectionValue,
getter_AddRefs(lb)))) {
return;
}
// Get the text fragment
nsCOMPtr<nsITextContent> tc = do_QueryInterface(mContent);
@ -2475,13 +2693,6 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
}
}
// Construct a text transformer
nsCOMPtr<nsIDocument> doc;
shell->GetDocument(getter_AddRefs(doc));
if (!doc)
return;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull, aPresContext);
// See if we need to transform the text. If the text fragment is ascii and
@ -2557,6 +2768,7 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
nsCOMPtr<nsIFrameSelection> frameSelection;
//get the frame selection
frameSelection = do_QueryInterface(selCon); //this MAY implement
nsresult rv = NS_OK;
if (!frameSelection)//if that failed get it from the presshell
rv = shell->GetFrameSelection(getter_AddRefs(frameSelection));
if (NS_SUCCEEDED(rv) && frameSelection){
@ -2593,7 +2805,7 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING
{
if (iter.CurrentBackGroundColor(currentBKColor))
if (iter.CurrentBackGroundColor(currentBKColor) && !isPaginated)
{//DRAW RECT HERE!!!
aRenderingContext.SetColor(currentBKColor);
aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height);
@ -2602,16 +2814,21 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
}
else
newWidth =0;
aRenderingContext.SetColor(currentFGColor);
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
if (isPaginated && !iter.IsBeforeOrAfter()) {
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
} else if (!isPaginated) {
aRenderingContext.SetColor(currentFGColor);
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
}
currentX+=newWidth;//increment twips X start
iter.Next();
}
}
else
else if (!isPaginated)
{
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
@ -4757,7 +4974,11 @@ nsTextFrame::List(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent) cons
// Output the rect and state
fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height);
if (0 != mState) {
fprintf(out, " [state=%08x]", mState);
if (mState & NS_FRAME_SELECTED_CONTENT) {
fprintf(out, " [state=%08x] SELECTED", mState);
} else {
fprintf(out, " [state=%08x]", mState);
}
}
fprintf(out, " sc=%p<\n", mStyleContext);

View File

@ -0,0 +1 @@
printing.properties

View File

@ -106,6 +106,7 @@ INCLUDES += \
-I$(srcdir)/../../../xul/base/src \
-I$(srcdir)/../../../xul/content/src \
-I$(srcdir)/../../style/src \
-I$(srcdir)/../../forms/src \
-I$(srcdir)/../../../base/src \
-I$(srcdir) \
$(NULL)

View File

@ -0,0 +1,3 @@
en-US.jar:
locale/en-US/communicator/printing.properties

View File

@ -123,6 +123,7 @@ CPP_OBJS= \
LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I$(PUBLIC)\js \
-I$(PUBLIC)\dom -I$(PUBLIC)\netlib -I$(PUBLIC)\unicharutil \
-I..\..\style\src \
-I..\..\forms\src \
-I..\..\..\base\src -I$(PUBLIC)\plugin -I$(PUBLIC)\java \
-I$(PUBLIC)\pref \
-I$(PUBLIC)\lwbrk \

View File

@ -6245,6 +6245,19 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext,
}
#endif
// Check to see if we are an absolutely positioned block (div)
// then then check to see if we need to paint.
const nsStylePosition* postionStyle = (const nsStylePosition*)
mStyleContext->GetStyleData(eStyleStruct_Position);
if (NS_STYLE_POSITION_RELATIVE == postionStyle->mPosition ||
NS_STYLE_POSITION_ABSOLUTE == postionStyle->mPosition ||
NS_STYLE_POSITION_FIXED == postionStyle->mPosition) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
}
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);

View File

@ -6245,6 +6245,19 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext,
}
#endif
// Check to see if we are an absolutely positioned block (div)
// then then check to see if we need to paint.
const nsStylePosition* postionStyle = (const nsStylePosition*)
mStyleContext->GetStyleData(eStyleStruct_Position);
if (NS_STYLE_POSITION_RELATIVE == postionStyle->mPosition ||
NS_STYLE_POSITION_ABSOLUTE == postionStyle->mPosition ||
NS_STYLE_POSITION_FIXED == postionStyle->mPosition) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
}
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);

View File

@ -6245,6 +6245,19 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext,
}
#endif
// Check to see if we are an absolutely positioned block (div)
// then then check to see if we need to paint.
const nsStylePosition* postionStyle = (const nsStylePosition*)
mStyleContext->GetStyleData(eStyleStruct_Position);
if (NS_STYLE_POSITION_RELATIVE == postionStyle->mPosition ||
NS_STYLE_POSITION_ABSOLUTE == postionStyle->mPosition ||
NS_STYLE_POSITION_FIXED == postionStyle->mPosition) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
}
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);

View File

@ -107,6 +107,7 @@ nsBulletFrame::GetFrameType(nsIAtom** aType) const
return NS_OK;
}
#include "nsIDOMNode.h"
NS_IMETHODIMP
nsBulletFrame::Paint(nsIPresContext* aCX,
nsIRenderingContext& aRenderingContext,
@ -117,10 +118,8 @@ nsBulletFrame::Paint(nsIPresContext* aCX,
return NS_OK;
}
const nsStyleDisplay* disp =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->IsVisible()) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aCX, aRenderingContext, PR_TRUE, &isVisible)) && isVisible) {
const nsStyleList* myList =
(const nsStyleList*)mStyleContext->GetStyleData(eStyleStruct_List);
PRUint8 listStyleType = myList->mListStyleType;

View File

@ -2308,6 +2308,58 @@ nsFrame::ParentDisablesSelection() const
return PR_FALSE;
}
NS_IMETHODIMP
nsFrame::IsVisibleForPainting(nsIPresContext * aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aCheckVis,
PRBool* aIsVisible)
{
// first check to see if we are visible
if (aCheckVis) {
nsIStyleContext* sc = mStyleContext;
const nsStyleDisplay* disp = (const nsStyleDisplay*)sc->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisible()) {
*aIsVisible = PR_FALSE;
return NS_OK;
}
}
// Start by assuming we are visible and need to be painted
PRBool isVisible = PR_TRUE;
// start by checking to see if we are paginated which probably means
// we are in print preview or printing
PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated);
if (isPaginated) {
// now see if we are rendering selection only
PRBool isRendingSelection;
aPresContext->IsRenderingOnlySelection(&isRendingSelection);
if (isRendingSelection) {
// Check the quick way first (typically only leaf nodes)
PRBool isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
// if we aren't selected in the mState,
// we could be a container so check to see if we are in the selection range
// this is a expensive
if (!isSelected) {
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
nsCOMPtr<nsISelectionController> selcon(do_QueryInterface(shell));
if (selcon) {
nsCOMPtr<nsISelection> selection;
selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mContent));
selection->ContainsNode(node, PR_TRUE, &isVisible);
} else {
isVisible = PR_FALSE;
}
}
}
}
*aIsVisible = isVisible;
return NS_OK;
}
NS_IMETHODIMP

View File

@ -278,6 +278,12 @@ public:
nsIFrame** aProviderFrame,
nsContextProviderRelationship& aRelationship);
// Check Style Visibility and mState for Selection (when printing)
NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aCheckVis,
PRBool* aIsVisible);
// nsIHTMLReflow
NS_IMETHOD WillReflow(nsIPresContext* aPresContext);
NS_IMETHOD Reflow(nsIPresContext* aPresContext,

View File

@ -20,7 +20,7 @@
* Contributor(s):
*/
#include "nsHTMLParts.h"
#include "nsContainerFrame.h"
#include "nsHTMLContainerFrame.h"
#include "nsCSSRendering.h"
#include "nsIDocument.h"
#include "nsIReflowCommand.h"

View File

@ -590,9 +590,9 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->IsVisible() && mRect.width && mRect.height) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) &&
isVisible && mRect.width && mRect.height) {
// First paint background and borders
nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect,
aWhichLayer);

View File

@ -40,6 +40,12 @@ nsLeafFrame::Paint(nsIPresContext* aPresContext,
nsFramePaintLayer aWhichLayer)
{
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) &&
!isVisible) {// just checks selection painting
return NS_OK; // not visibility
}
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->IsVisibleOrCollapsed()) {

View File

@ -31,6 +31,27 @@
#include "nsLayoutAtoms.h"
#include "nsIStyleSet.h"
#include "nsIPresShell.h"
#include "nsIDeviceContext.h"
// for page number localization formatting
#include "nsTextFormatter.h"
// DateTime Includes
#include "nsDateTimeFormatCID.h"
#include "nsIDateTimeFormat.h"
#include "nsIServiceManager.h"
#include "nsILocale.h"
#include "nsLocaleCID.h"
#include "nsILocaleService.h"
static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID);
static NS_DEFINE_CID(kLocaleServiceCID, NS_LOCALESERVICE_CID);
// Temporary
#include "nsIFontMetrics.h"
// tstaic data members
PRUnichar * nsPageFrame::mPageNumFormat = nsnull;
nsresult
NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
@ -47,10 +68,22 @@ NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
return NS_OK;
}
nsPageFrame::nsPageFrame()
nsPageFrame::nsPageFrame() :
mHeadFootFont(nsnull)
{
}
nsPageFrame::~nsPageFrame()
{
if (mHeadFootFont)
delete mHeadFootFont;
if (mPageNumFormat) {
nsMemory::Free(mPageNumFormat);
mPageNumFormat = nsnull;
}
}
NS_METHOD nsPageFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
@ -173,3 +206,253 @@ nsPageFrame::IsPercentageBase(PRBool& aBase) const
aBase = PR_TRUE;
return NS_OK;
}
//------------------------------------------------------------------------------
nscoord nsPageFrame::GetXPosition(nsIRenderingContext& aRenderingContext,
const nsRect& aRect,
PRInt32 aJust,
const nsString& aStr)
{
PRInt32 width;
aRenderingContext.GetWidth(aStr, width);
nscoord x = aRect.x;
switch (aJust) {
case NS_PRINT_JUSTIFY_LEFT:
// do nothing, already set
break;
case NS_PRINT_JUSTIFY_CENTER:
x += (aRect.width - width) / 2;
break;
case NS_PRINT_JUSTIFY_RIGHT:
x += aRect.width - width;
break;
} // switch
return x;
}
//------------------------------------------------------------------------------
// Draw a Header or footer text lrft,right or center justified
// @parm aRenderingContext - rendering content ot draw into
// @parm aHeaderFooter - indicates whether it is a header or footer
// @parm aJust - indicates the justification of the text
// @parm aStr - The string to be drawn
// @parm aRect - the rect of the page
// @parm aHeight - the height of the text
// @parm aUseHalfThePage - indicates whether the text should limited to the width
// of the entire page or just half the page
void
nsPageFrame::DrawHeaderFooter(nsIRenderingContext& aRenderingContext,
nsIFrame * aFrame,
nsHeaderFooterEnum aHeaderFooter,
PRInt32 aJust,
const nsString& aStr,
const nsRect& aRect,
nscoord aHeight,
PRBool aUseHalfThePage)
{
// first make sure we have a vaild string and that the height of the
// text will fit in the margin
if (aStr.Length() > 0 &&
((aHeaderFooter == eHeader && aHeight < mMargin.top) ||
(aHeaderFooter == eFooter && aHeight < mMargin.bottom))) {
// measure the width of the text
nsString str = aStr;
PRInt32 width;
aRenderingContext.GetWidth(str, width);
PRBool addEllipse = PR_FALSE;
nscoord halfWidth = aRect.width;
if (aUseHalfThePage) {
halfWidth /= 2;
}
// trim the text and add the elipses if it won't fit
while (width >= halfWidth && str.Length() > 1) {
str.SetLength(str.Length()-1);
aRenderingContext.GetWidth(str, width);
addEllipse = PR_TRUE;
}
if (addEllipse && str.Length() > 3) {
str.SetLength(str.Length()-3);
str.AppendWithConversion("...");
aRenderingContext.GetWidth(str, width);
}
// cacl the x and y positions of the text
nsRect rect(aRect);
nscoord x = GetXPosition(aRenderingContext, rect, aJust, str);
nscoord y;
if (aHeaderFooter == eHeader) {
nscoord offset = ((mMargin.top - aHeight) / 2);
y = rect.y - offset - aHeight;
rect.Inflate(0, offset + aHeight);
} else {
nscoord offset = ((mMargin.bottom - aHeight) / 2);
y = rect.y + rect.height + offset;
rect.height += offset + aHeight;
}
// set up new clip and draw the text
PRBool clipEmpty;
aRenderingContext.PushState();
aRenderingContext.SetClipRect(rect, nsClipCombine_kReplace, clipEmpty);
aRenderingContext.DrawString(str, x, y);
aRenderingContext.PopState(clipEmpty);
}
}
//------------------------------------------------------------------------------
NS_IMETHODIMP
nsPageFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
nsresult rv = nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// get the current margin
mPrintOptions->GetMargin(mMargin);
nsRect rect(0,0,mRect.width, mRect.height);
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
// XXX Paint a one-pixel border around the page so it's easy to see where
// each page begins and ends when we're
float p2t;
aPresContext->GetPixelsToTwips(&p2t);
rect.Deflate(NSToCoordRound(p2t), NSToCoordRound(p2t));
aRenderingContext.SetColor(NS_RGB(0, 0, 0));
//aRenderingContext.DrawRect(rect);
rect.Inflate(NSToCoordRound(p2t), NSToCoordRound(p2t));
printf("SPSF::PaintChild -> Painting Frame %p Page No: %d\n", this, mPageNum);
#endif
// use the whole page
rect.width += mMargin.left + mMargin.right;
rect.x -= mMargin.left;
aRenderingContext.SetFont(*mHeadFootFont);
aRenderingContext.SetColor(NS_RGB(0,0,0));
// Get the FontMetrics to determine width.height of strings
nsCOMPtr<nsIDeviceContext> deviceContext;
aPresContext->GetDeviceContext(getter_AddRefs(deviceContext));
NS_ASSERTION(deviceContext, "Couldn't get the device context");
nsCOMPtr<nsIFontMetrics> fontMet;
deviceContext->GetMetricsFor(*mHeadFootFont, *getter_AddRefs(fontMet));
nscoord visibleHeight = 0;
if (fontMet) {
fontMet->GetHeight(visibleHeight);
}
// get the print options bits so we can figure out all the
// the extra pieces of text that need to be drawn
PRInt32 printOptBits;
mPrintOptions->GetPrintOptionsBits(&printOptBits);
// print page numbers
if (printOptBits & NS_PRINT_OPTIONS_PRINT_PAGE_NUMS && mPageNumFormat != nsnull) {
PRInt32 justify = NS_PRINT_JUSTIFY_LEFT;
mPrintOptions->GetPageNumJust(&justify);
PRUnichar * valStr;
// print page number totals "x of x"
if (printOptBits & NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL) {
valStr = nsTextFormatter::smprintf(mPageNumFormat, mPageNum, mTotNumPages);
} else {
valStr = nsTextFormatter::smprintf(mPageNumFormat, mPageNum);
}
nsAutoString pageNoStr(valStr);
nsMemory::Free(valStr);
DrawHeaderFooter(aRenderingContext, this, eFooter, justify, pageNoStr, rect, visibleHeight);
}
// print localized date
if (printOptBits & NS_PRINT_OPTIONS_PRINT_DATE_PRINTED) {
// Get Locale for Formating DateTime
nsCOMPtr<nsILocale> locale;
NS_WITH_SERVICE(nsILocaleService, localeSvc, kLocaleServiceCID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = localeSvc->GetApplicationLocale(getter_AddRefs(locale));
if (NS_SUCCEEDED(rv) && locale) {
nsCOMPtr<nsIDateTimeFormat> dateTime;
rv = nsComponentManager::CreateInstance(kDateTimeFormatCID,
NULL,
NS_GET_IID(nsIDateTimeFormat),
(void**) getter_AddRefs(dateTime));
if (NS_SUCCEEDED(rv)) {
nsAutoString dateString;
time_t ltime;
time( &ltime );
rv = dateTime->FormatTMTime(locale, kDateFormatShort, kTimeFormatNoSeconds, localtime( &ltime ), dateString);
if (NS_SUCCEEDED(rv)) {
DrawHeaderFooter(aRenderingContext, this, eFooter, NS_PRINT_JUSTIFY_RIGHT, dateString, rect, visibleHeight);
}
}
}
}
}
PRBool usingHalfThePage = (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_TITLE) && (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_LOCATION);
// print document title
PRUnichar * title;
mPrintOptions->GetTitle(&title); // creates memory
if (title != nsnull && (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_TITLE)) {
DrawHeaderFooter(aRenderingContext, this, eHeader, NS_PRINT_JUSTIFY_LEFT, nsAutoString(title), rect, visibleHeight, usingHalfThePage);
nsMemory::Free(title);
}
// print document URL
PRUnichar * url;
mPrintOptions->GetURL(&url);
if (title != url && (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_LOCATION)) {
DrawHeaderFooter(aRenderingContext, this, eHeader, NS_PRINT_JUSTIFY_RIGHT, nsAutoString(url), rect, visibleHeight, usingHalfThePage);
nsMemory::Free(url);
}
}
return rv;
}
//------------------------------------------------------------------------------
void
nsPageFrame::SetPrintOptions(nsIPrintOptions * aPrintOptions)
{
NS_ASSERTION(aPrintOptions != nsnull, "Print Options can not be null!");
mPrintOptions = aPrintOptions;
// create a default font
mHeadFootFont = new nsFont("serif", NS_FONT_STYLE_NORMAL,NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL,0,NSIntPointsToTwips(10));
// now get the default font form the print options
mPrintOptions->GetDefaultFont(*mHeadFootFont);
}
//------------------------------------------------------------------------------
void
nsPageFrame::SetPageNumInfo(PRInt32 aPageNumber, PRInt32 aTotalPages)
{
mPageNum = aPageNumber;
mTotNumPages = aTotalPages;
}
//------------------------------------------------------------------------------
void
nsPageFrame::SetPageNumberFormat(PRUnichar * aFormatStr)
{
NS_ASSERTION(aFormatStr != nsnull, "Format string cannot be null!");
if (mPageNumFormat != nsnull) {
nsMemory::Free(mPageNumFormat);
}
mPageNumFormat = aFormatStr;
}

View File

@ -22,17 +22,25 @@
#ifndef nsPageFrame_h___
#define nsPageFrame_h___
#include "nsHTMLContainerFrame.h"
#include "nsContainerFrame.h"
#include "nsIPrintOptions.h"
// Page frame class used by the simple page sequence frame
class nsPageFrame : public nsContainerFrame {
public:
friend nsresult NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
// nsIFrame
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aMaxSize,
nsReflowStatus& aStatus);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
NS_IMETHOD IsPercentageBase(PRBool& aBase) const;
/**
@ -47,8 +55,51 @@ public:
NS_IMETHOD GetFrameName(nsString& aResult) const;
#endif
//////////////////
// For Printing
//////////////////
// Set the print options object into the page for printing
virtual void SetPrintOptions(nsIPrintOptions * aPrintOptions);
// Tell the page which page number it is out of how many
virtual void SetPageNumInfo(PRInt32 aPageNumber, PRInt32 aTotalPages);
// This is class is now responsible for freeing the memory
static void SetPageNumberFormat(PRUnichar * aFormatStr);
protected:
nsPageFrame();
virtual ~nsPageFrame();
typedef enum {
eHeader,
eFooter
} nsHeaderFooterEnum;
nscoord GetXPosition(nsIRenderingContext& aRenderingContext,
const nsRect& aRect,
PRInt32 aJust,
const nsString& aStr);
void DrawHeaderFooter(nsIRenderingContext& aRenderingContext,
nsIFrame * aFrame,
nsHeaderFooterEnum aHeaderFooter,
PRInt32 aJust,
const nsString& sStr,
const nsRect& aRect,
nscoord aHeight,
PRBool aUseHalfThePage = PR_TRUE);
nsCOMPtr<nsIPrintOptions> mPrintOptions;
PRInt32 mPageNum;
PRInt32 mTotNumPages;
nsMargin mMargin;
nsFont * mHeadFootFont;
static PRUnichar * mPageNumFormat;
};
#endif /* nsPageFrame_h___ */

View File

@ -31,6 +31,24 @@
#include "nsIViewManager.h"
#include "nsIPresShell.h"
#include "nsIStyleSet.h"
#include "nsIFontMetrics.h"
#include "nsIPrintOptions.h"
#include "nsPageFrame.h"
#define OFFSET_NOT_SET -1
// This is for localization of the "x of n" pages string
// this class contains a helper method we need to get
// a string from a string bundle
#include "nsFormControlHelper.h"
#define PRINTING_PROPERTIES "chrome://communicator/locale/printing.properties"
// Print Options
#include "nsIPrintOptions.h"
#include "nsGfxCIID.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID);
//
nsresult
NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
@ -47,7 +65,28 @@ NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
return NS_OK;
}
nsSimplePageSequenceFrame::nsSimplePageSequenceFrame()
nsSimplePageSequenceFrame::nsSimplePageSequenceFrame() :
mIsPrintingSelection(PR_FALSE)
{
mStartOffset = OFFSET_NOT_SET;
mEndOffset = OFFSET_NOT_SET;
nscoord halfInch = NS_INCHES_TO_TWIPS(0.5);
mMargin.SizeTo(halfInch, halfInch, halfInch, halfInch);
// XXX this code and the object data member "mIsPrintingSelection" is only needed
// for the hack for printing selection where we make the page the max size
nsresult rv;
NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv);
if (NS_SUCCEEDED(rv) && printService) {
PRInt32 printType;
printService->GetPrintRange(&printType);
mIsPrintingSelection = ePrintRange_Selection == nsPrintRange(printType);
}
}
nsSimplePageSequenceFrame::~nsSimplePageSequenceFrame()
{
}
@ -67,9 +106,6 @@ nsSimplePageSequenceFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr
//----------------------------------------------------------------------
// XXX Hack
#define PAGE_SPACING_TWIPS 100
// Creates a continuing page frame
nsresult
nsSimplePageSequenceFrame::CreateContinuingPageFrame(nsIPresContext* aPresContext,
@ -110,12 +146,10 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext* aPresConte
aReflowState.reflowCommand->GetNext(nextFrame);
// Compute the y-offset of this page
for (nsIFrame* f = mFrames.FirstChild(); f != nextFrame;
f->GetNextSibling(&f)) {
for (nsIFrame* f = mFrames.FirstChild(); f != nextFrame; f->GetNextSibling(&f)) {
nsSize size;
f->GetSize(size);
aY += size.height + PAGE_SPACING_TWIPS;
aY += size.height + mMargin.top + mMargin.bottom;
}
// Reflow the page
@ -131,7 +165,7 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext* aPresConte
// Place and size the page. If the page is narrower than our max width, then
// center it horizontally
FinishReflowChild(nextFrame, aPresContext, kidSize, aX, aY, 0);
aY += kidSize.height + PAGE_SPACING_TWIPS;
aY += kidSize.height + mMargin.top + mMargin.bottom;
// Check if the page is complete...
nsIFrame* kidNextInFlow;
@ -174,7 +208,7 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext* aPresConte
aY += childSize.height;
// Leave a slight gap between the pages
aY += PAGE_SPACING_TWIPS;
aY += mMargin.top + mMargin.bottom;
// Is the page complete?
kidFrame->GetNextInFlow(&kidNextInFlow);
@ -216,15 +250,21 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext,
nsSize pageSize;
aPresContext->GetPageWidth(&pageSize.width);
aPresContext->GetPageHeight(&pageSize.height);
PRInt32 extra = aReflowState.availableWidth - 2 * PAGE_SPACING_TWIPS - pageSize.width;
nscoord x = PAGE_SPACING_TWIPS;
if (extra > 0) {
x += extra / 2;
// XXX - Hack Alert
// OK, so ther eis a selection, we will print the entire selection
// on one page and then crop the page.
// This means you can never print any selection that is longer than one page
// put it keeps it from page breaking in the middle of your print of the selection
// (see also nsDocumentViewer.cpp)
if (mIsPrintingSelection) {
pageSize.height = 0x0FFFFFFF;
}
nscoord x = mMargin.left;
// Running y-offset for each page
nscoord y = PAGE_SPACING_TWIPS;
nscoord y = mMargin.top;
// See if it's an incremental reflow command
if (eReflowReason_Incremental == aReflowState.reason) {
@ -240,6 +280,10 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
pageSize, reflowReason);
nsReflowStatus status;
kidReflowState.availableWidth = pageSize.width - mMargin.left - mMargin.right;
kidReflowState.availableHeight = pageSize.height - mMargin.top - mMargin.bottom;
kidReflowState.mComputedWidth = kidReflowState.availableWidth;
//kidReflowState.mComputedHeight = kidReflowState.availableHeight;
// Place and size the page. If the page is narrower than our
// max width then center it horizontally
@ -248,8 +292,16 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext,
FinishReflowChild(kidFrame, aPresContext, kidSize, x, y, 0);
y += kidSize.height;
nsIView* view;
kidFrame->GetView(aPresContext, &view);
NS_ASSERTION(nsnull != view, "no page view");
nsRect rect;
kidFrame->GetRect(rect);
nsRect viewRect;
view->GetBounds(viewRect);
// Leave a slight gap between the pages
y += PAGE_SPACING_TWIPS;
y += mMargin.top + mMargin.bottom;
// Is the page complete?
nsIFrame* kidNextInFlow;
@ -274,9 +326,9 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext,
}
// Return our desired size
aDesiredSize.height = y;
aDesiredSize.width = 2*PAGE_SPACING_TWIPS + pageSize.width;
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.height = y;
aDesiredSize.width = pageSize.width;
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
NS_FRAME_TRACE_REFLOW_OUT("nsSimplePageSequeceFrame::Reflow", aStatus);
@ -293,53 +345,6 @@ nsSimplePageSequenceFrame::GetFrameName(nsString& aResult) const
}
#endif
NS_IMETHODIMP
nsSimplePageSequenceFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
// Paint a white background
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,
aWhichLayer);
}
void
nsSimplePageSequenceFrame::PaintChild(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsIFrame* aFrame,
nsFramePaintLayer aWhichLayer)
{
// Let the page paint
nsContainerFrame::PaintChild(aPresContext, aRenderingContext,
aDirtyRect, aFrame, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// 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(&p2t);
aRenderingContext.SetColor(NS_RGB(0, 0, 0));
aFrame->GetRect(pageBounds);
pageBounds.Inflate(NSToCoordRound(p2t), NSToCoordRound(p2t));
// this paints a rectangle around the for the printer output,
// which sometimes appears, other times
// goes away. I have to look into this further or ask troy..
// I took it out for the time being to fix some bugs -- dwc
//aRenderingContext.DrawRect(pageBounds);
}
}
//----------------------------------------------------------------------
// Helper function that sends the progress notification. Returns PR_TRUE
@ -361,15 +366,37 @@ SendStatusNotification(nsIPrintStatusCallback* aStatusCallback,
NS_IMETHODIMP
nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext,
const nsPrintOptions& aPrintOptions,
nsIPrintOptions* aPrintOptions,
nsIPrintStatusCallback* aStatusCallback)
{
NS_ENSURE_ARG_POINTER(aPresContext);
NS_ENSURE_ARG_POINTER(aPrintOptions);
nsPrintRange printRangeType;
PRInt32 fromPageNum;
PRInt32 toPageNum;
PRInt32 marginL, marginR, marginT, marginB;
PRBool printEvenPages, printOddPages;
PRInt32 printType;
aPrintOptions->GetPrintRange(&printType);
printRangeType = (nsPrintRange)printType;
aPrintOptions->GetPageRange(&fromPageNum, &toPageNum);
aPrintOptions->GetMargins(&marginT, &marginL, &marginR, &marginB);
mMargin.SizeTo(nscoord(marginL), nscoord(marginT), nscoord(marginR), nscoord(marginB));
aPrintOptions->GetPrintOptions(NS_PRINT_OPTIONS_PRINT_EVEN_PAGES, &printEvenPages);
aPrintOptions->GetPrintOptions(NS_PRINT_OPTIONS_PRINT_ODD_PAGES, &printOddPages);
PRBool doingPageRange = ePrintRange_SpecifiedPageRange == printRangeType ||
ePrintRange_Selection == printRangeType;
// If printing a range of pages make sure at least the starting page
// number is valid
PRInt32 totalPages = mFrames.GetLength();
if (ePrintRange_SpecifiedRange == aPrintOptions.range) {
if (aPrintOptions.startPage > totalPages) {
if (doingPageRange) {
if (fromPageNum > totalPages) {
return NS_ERROR_INVALID_ARG;
}
}
@ -383,29 +410,158 @@ nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext,
presShell->GetViewManager(getter_AddRefs(vm));
nsresult rv = NS_OK;
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
{
nsIView * seqView;
GetView(aPresContext, &seqView);
nsRect rect;
GetRect(rect);
printf("Seq Frame: - %d,%d,%d,%d ", rect.x, rect.y, rect.width, rect.height);
printf("view: %p ", seqView);
nsRect viewRect;
if (seqView) {
seqView->GetBounds(viewRect);
printf(" %d,%d,%d,%d", viewRect.x, viewRect.y, viewRect.width, viewRect.height);
}
printf("\n");
}
{
PRInt32 pageNum = 1;
for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) {
nsIView* view;
page->GetView(aPresContext, &view);
NS_ASSERTION(nsnull != view, "no page view");
nsRect rect;
page->GetRect(rect);
nsRect viewRect;
view->GetBounds(viewRect);
printf("Page: %d - %d,%d,%d,%d ", pageNum, rect.x, rect.y, rect.width, rect.height);
printf(" %d,%d,%d,%d\n", viewRect.x, viewRect.y, viewRect.width, viewRect.height);
pageNum++;
}
}
printf("***** Setting aPresContext %p is painting selection %d\n", aPresContext, ePrintRange_Selection == printRangeType);
#endif
// Determine if we are rendering only the selection
aPresContext->SetIsRenderingOnlySelection(ePrintRange_Selection == printRangeType);
if (doingPageRange) {
// XXX because of the hack for making the selection all print on one page
// we must make sure that the page is sized correctly before printing.
PRInt32 width,height;
dc->GetDeviceSurfaceDimensions(width,height);
height -= mMargin.top + mMargin.bottom;
PRInt32 pageNum = 1;
nscoord y = mMargin.top;
for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) {
nsIView* view;
page->GetView(aPresContext, &view);
NS_ASSERTION(nsnull != view, "no page view");
if (pageNum < fromPageNum || pageNum > toPageNum) {
// XXX Doesn't seem like we need to do this
// because we ask only the pages we want to print
//view->SetVisibility(nsViewVisibility_kHide);
} else {
nsRect rect;
page->GetRect(rect);
rect.y = y;
rect.height = height;
page->SetRect(aPresContext, rect);
nsRect viewRect;
view->GetBounds(viewRect);
viewRect.y = y;
viewRect.height = height;
view->SetBounds(viewRect);
y += rect.height + mMargin.top + mMargin.bottom;
}
pageNum++;
}
// adjust total number of pages
if (ePrintRange_Selection == printRangeType) {
totalPages = toPageNum - fromPageNum + 1;
} else {
totalPages = pageNum - 1;
}
}
// XXX - This wouldn't have to be done each time
// but it isn't that expensive and this the best place
// to have access to a localized file properties file
//
// Note: because this is done here it makes a little bit harder
// to have UI for setting the header/footer font name and size
//
// Get default font name and size to be used for the headers and footers
nsAutoString fontName;
rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, "fontname", fontName);
if (NS_FAILED(rv)) {
fontName.AssignWithConversion("serif");
}
nsAutoString fontSizeStr;
nscoord pointSize = 10;;
rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, "fontsize", fontSizeStr);
if (NS_SUCCEEDED(rv)) {
PRInt32 errCode;
pointSize = fontSizeStr.ToInteger(&errCode);
if (NS_FAILED(errCode)) {
pointSize = 10;
}
}
aPrintOptions->SetFontNamePointSize(fontName, pointSize);
// Now go get the Localized Page Formating String
PRBool doingPageTotals = PR_TRUE;
aPrintOptions->GetPrintOptions(NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL, &doingPageTotals);
nsAutoString pageFormatStr;
rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES,
doingPageTotals?"pageofpages":"pagenumber",
pageFormatStr);
if (NS_FAILED(rv)) { // back stop formatting
pageFormatStr.AssignWithConversion(doingPageTotals?"%ld of %ld":"%ld");
}
// Sets the format into a static data memeber which will own the memory and free it
nsPageFrame::SetPageNumberFormat(pageFormatStr.ToNewUnicode());
// Print each specified page
PRInt32 pageNum = 1;
// pageNum keeps track of the current page and what pages are printing
//
// printedPageNum keeps track of the current page number to be printed
// Note: When print al the pages or a page range the printed page shows the
// actual page number, when printing selection it prints the page number starting
// with the first page of the selection. For example if the user has a
// selection that starts on page 2 and ends on page 3, the page numbers when
// print are 1 and then two (which is different than printing a page range, where
// the page numbers would have been 2 and then 3)
PRInt32 pageNum = 1;
PRInt32 printedPageNum = 1;
for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) {
// See whether we should print this page
PRBool printThisPage = PR_TRUE;
// 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) {
if (doingPageRange) {
if (pageNum < fromPageNum) {
printThisPage = PR_FALSE;
} else if (pageNum > aPrintOptions.endPage) {
} else if (pageNum > toPageNum) {
break;
}
}
// Check for printing of odd and even pages
if (pageNum & 0x1) {
if (!aPrintOptions.oddNumberedPages) {
if (!printOddPages) {
printThisPage = PR_FALSE; // don't print odd numbered page
}
} else {
if (!aPrintOptions.evenNumberedPages) {
if (!printEvenPages) {
printThisPage = PR_FALSE; // don't print even numbered page
}
}
@ -424,18 +580,37 @@ nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext,
}
break;
}
// cast the frame to be a page frame
nsPageFrame * pf = NS_STATIC_CAST(nsPageFrame*, page);
if (pf != nsnull) {
pf->SetPrintOptions(aPrintOptions);
pf->SetPageNumInfo(printedPageNum, totalPages);
}
// Print the page
nsIView* view;
page->GetView(aPresContext, &view);
NS_ASSERTION(nsnull != view, "no page view");
vm->Display(view);
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
{
char * fontname = fontName.ToNewCString();
printf("SPSF::Paint -> FontName[%s] Point Size: %d\n", fontname, pointSize);
nsMemory::Free(fontname);
printf("SPSF::Paint -> PageNo: %d View: %p\n", pageNum, view);
}
#endif
vm->Display(view, mMargin.left, mMargin.top);
// this view was printed and since display set the origin
// 0,0 there is a danger that this view can be printed again
// If it is a sibling to another page/view. Setting the visibility
// to hide will keep this page from printing again - dwc
view->SetVisibility(nsViewVisibility_kHide);
//
// XXX Doesn't seem like we need to do this anymore
//view->SetVisibility(nsViewVisibility_kHide);
// Finish printing of the page
if (!SendStatusNotification(aStatusCallback, pageNum, totalPages,
@ -452,9 +627,21 @@ nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext,
}
}
// Increment the page number
if (ePrintRange_Selection != printRangeType ||
(ePrintRange_Selection == printRangeType && printThisPage)) {
printedPageNum++;
}
pageNum++;
}
return rv;
}
NS_IMETHODIMP
nsSimplePageSequenceFrame::SetOffsets(nscoord aStartOffset, nscoord aEndOffset)
{
mStartOffset = aStartOffset;
mEndOffset = aEndOffset;
return NS_OK;
}

View File

@ -22,8 +22,9 @@
#ifndef nsSimplePageSequence_h___
#define nsSimplePageSequence_h___
#include "nsHTMLContainerFrame.h"
#include "nsIPageSequenceFrame.h"
#include "nsContainerFrame.h"
#include "nsIPrintOptions.h"
// Simple page sequence frame class. Used when we're in paginated mode
class nsSimplePageSequenceFrame : public nsContainerFrame,
@ -40,16 +41,12 @@ public:
const nsHTMLReflowState& aMaxSize,
nsReflowStatus& aStatus);
// nsIFrame
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
// nsIPageSequenceFrame
NS_IMETHOD Print(nsIPresContext* aPresContext,
const nsPrintOptions& aPrintOptions,
nsIPrintOptions* aPrintOptions,
nsIPrintStatusCallback* aStatusCallback);
NS_IMETHOD SetOffsets(nscoord aStartOffset, nscoord aEndOffset);
NS_IMETHOD SetPageNo(PRInt32 aPageNo) { return NS_OK;}
#ifdef DEBUG
// Debugging
@ -58,11 +55,7 @@ public:
protected:
nsSimplePageSequenceFrame();
virtual void PaintChild(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsIFrame* aFrame,
nsFramePaintLayer aWhichLayer);
virtual ~nsSimplePageSequenceFrame();
nsresult IncrementalReflow(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
@ -73,9 +66,14 @@ protected:
nsresult CreateContinuingPageFrame(nsIPresContext* aPresContext,
nsIFrame* aPageFrame,
nsIFrame** aContinuingFrame);
NS_IMETHOD_(nsrefcnt) AddRef(void) {return nsContainerFrame::AddRef();}
NS_IMETHOD_(nsrefcnt) Release(void) {return nsContainerFrame::Release();}
nscoord mStartOffset;
nscoord mEndOffset;
nsMargin mMargin;
PRBool mIsPrintingSelection;
};
#endif /* nsSimplePageSequence_h___ */

View File

@ -427,6 +427,11 @@ public:
PRInt32* outFrameContentOffset,
nsIFrame* *outChildFrame);
NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aCheckVis,
PRBool* aIsVisible);
// nsIHTMLReflow
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
@ -659,6 +664,19 @@ public:
PRUnichar* aBuffer, PRInt32 aLength,
nscoord aWidth);
PRBool IsTextInSelection(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext);
nsresult GetTextInfoForPainting(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIPresShell** aPresShell,
nsISelectionController** aSelectionController,
PRBool& aDisplayingSelection,
PRBool& aIsPaginated,
PRBool& aIsSelected,
PRInt16& aSelectionValue,
nsILineBreaker** aLineBreaker);
void PaintUnicodeText(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIStyleContext* aStyleContext,
@ -805,6 +823,7 @@ public:
nsTextFrame::TextStyle & CurrentStyle();
nscolor CurrentForeGroundColor();
PRBool CurrentBackGroundColor(nscolor &aColor);
PRBool IsBeforeOrAfter();
private:
union {
PRUnichar *mUniStr;
@ -1042,6 +1061,11 @@ DrawSelectionIterator::CurrentBackGroundColor(nscolor &aColor)
return PR_FALSE;
}
PRBool
DrawSelectionIterator::IsBeforeOrAfter()
{
return mCurrentIdx != (PRUint32)mDetails->mStart;
}
//END DRAWSELECTIONITERATOR!!
@ -1219,9 +1243,8 @@ nsTextFrame::Paint(nsIPresContext* aPresContext,
return NS_OK;
}
nsIStyleContext* sc = mStyleContext;
const nsStyleDisplay* disp = (const nsStyleDisplay*)
sc->GetStyleData(eStyleStruct_Display);
if (disp->IsVisible()) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && isVisible) {
TextStyle ts(aPresContext, aRenderingContext, mStyleContext);
if (ts.mSmallCaps || (0 != ts.mWordSpacing) || (0 != ts.mLetterSpacing)
|| ts.mJustifying) {
@ -1261,6 +1284,7 @@ nsTextFrame::Paint(nsIPresContext* aPresContext,
// Use char rendering routine
PaintAsciiText(aPresContext, aRenderingContext, sc, ts, 0, 0);
}
}
}
return NS_OK;
@ -1735,6 +1759,194 @@ nsTextFrame::GetContentAndOffsetsForSelection(nsIPresContext *aPresContext, nsIC
return NS_OK;
}
//---------------------------------------------------------
nsresult nsTextFrame::GetTextInfoForPainting(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIPresShell** aPresShell,
nsISelectionController** aSelectionController,
PRBool& aDisplayingSelection,
PRBool& aIsPaginated,
PRBool& aIsSelected,
PRInt16& aSelectionValue,
nsILineBreaker** aLineBreaker)
{
NS_ENSURE_ARG_POINTER(aPresContext);
NS_ENSURE_ARG_POINTER(aPresShell);
NS_ENSURE_ARG_POINTER(aSelectionController);
NS_ENSURE_ARG_POINTER(aLineBreaker);
//get the presshell
nsresult rv = aPresContext->GetShell(aPresShell);
if (NS_FAILED(rv) || (*aPresShell) == nsnull)
return NS_ERROR_FAILURE;
//get the selection controller
rv = GetSelectionController(aPresContext, aSelectionController);
if (NS_FAILED(rv) || !(*aSelectionController))
return NS_ERROR_FAILURE;
aPresContext->IsPaginated(&aIsPaginated);
PRBool isRenderingOnlySelection;
aPresContext->IsRenderingOnlySelection(&isRenderingOnlySelection);
(*aSelectionController)->GetDisplaySelection(&aSelectionValue);
//if greater than hidden then we display some kind of selection
aDisplayingSelection = (aSelectionValue > nsISelectionController::SELECTION_HIDDEN) ||
(aIsPaginated && isRenderingOnlySelection);
// Transform text from content into renderable form
// XXX If the text fragment is already Unicode and text text wasn't
// transformed when we formatted it, then there's no need to do all
// this and we should just render the text fragment directly. See
// PaintAsciiText()...
nsCOMPtr<nsIDocument> doc;
(*aPresShell)->GetDocument(getter_AddRefs(doc));
if (!doc)
return NS_ERROR_FAILURE;
doc->GetLineBreaker(aLineBreaker);
nsFrameState frameState;
GetFrameState(&frameState);
aIsSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
return NS_OK;
}
PRBool
nsTextFrame::IsTextInSelection(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext)
{
nsCOMPtr<nsISelectionController> selCon;
nsCOMPtr<nsIPresShell> shell;
PRBool displaySelection;
PRBool isPaginated;
PRBool isSelected;
PRInt16 selectionValue;
nsCOMPtr<nsILineBreaker> lb;
if (NS_FAILED(GetTextInfoForPainting(aPresContext,
aRenderingContext,
getter_AddRefs(shell),
getter_AddRefs(selCon),
displaySelection,
isPaginated,
isSelected,
selectionValue,
getter_AddRefs(lb)))) {
return PR_FALSE;
}
// Make enough space to transform
nsAutoTextBuffer paintBuffer;
nsAutoIndexBuffer indexBuffer;
if (NS_FAILED(indexBuffer.GrowTo(mContentLength + 1))) {
return PR_FALSE;
}
TextStyle ts(aPresContext, aRenderingContext, mStyleContext);
// Transform text from content into renderable form
// XXX If the text fragment is already Unicode and text text wasn't
// transformed when we formatted it, then there's no need to do all
// this and we should just render the text fragment directly. See
// PaintAsciiText()...
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 textLength;
// no need to worry about justification, that's always on the slow path
PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
PRInt32* ip = indexBuffer.mBuffer;
PRUnichar* text = paintBuffer.mBuffer;
if (0 != textLength) {
SelectionDetails *details = nsnull;
nsCOMPtr<nsIFrameSelection> frameSelection;
//get the frameSelection from the selection controller
if (selCon) {
frameSelection = do_QueryInterface(selCon); //this MAY implement
}
nsresult rv = NS_OK;
//if that failed get it from the pres shell
if (!frameSelection)
rv = shell->GetFrameSelection(getter_AddRefs(frameSelection));
if (NS_SUCCEEDED(rv) && frameSelection){
nsCOMPtr<nsIContent> content;
PRInt32 offset;
PRInt32 length;
rv = GetContentAndOffsetsForSelection(aPresContext,getter_AddRefs(content),&offset,&length);
if (NS_SUCCEEDED(rv) && content){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &details, PR_FALSE);
}
}
//where are the selection points "really"
SelectionDetails *sdptr = details;
while (sdptr){
sdptr->mStart = ip[sdptr->mStart] - mContentOffset;
sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset;
sdptr = sdptr->mNext;
}
//while we have substrings...
//PRBool drawn = PR_FALSE;
DrawSelectionIterator iter(details,text,(PRUint32)textLength, ts, nsISelectionController::SELECTION_NORMAL);
if (!iter.IsDone() && iter.First()) {
return PR_TRUE;
}
sdptr = details;
if (details) {
while ((sdptr = details->mNext) != nsnull) {
delete details;
details = sdptr;
}
delete details;
}
}
return PR_FALSE;
}
NS_IMETHODIMP
nsTextFrame::IsVisibleForPainting(nsIPresContext * aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aCheckVis,
PRBool* aIsVisible)
{
if (aCheckVis) {
nsIStyleContext* sc = mStyleContext;
const nsStyleDisplay* disp = (const nsStyleDisplay*)sc->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisible()) {
*aIsVisible = PR_FALSE;
return NS_OK;
}
}
// Start by assuming we are visible and need to be painted
PRBool isVisible = PR_TRUE;
PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated);
if (isPaginated) {
PRBool isRendingSelection;
aPresContext->IsRenderingOnlySelection(&isRendingSelection);
if (isRendingSelection) {
// Check the quick way first
PRBool isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (isSelected) {
isVisible = IsTextInSelection(aPresContext, aRenderingContext);
} else {
isVisible = PR_FALSE;
}
}
}
*aIsVisible = isVisible;
return NS_OK;
}
void
nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
@ -1743,22 +1955,24 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
TextStyle& aTextStyle,
nscoord dx, nscoord dy)
{
nsCOMPtr<nsIPresShell> shell;
//get the presshell
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_FAILED(rv) || !shell)
return;
//get the selection controller
nsCOMPtr<nsISelectionController> selCon;
rv = GetSelectionController(aPresContext, getter_AddRefs(selCon));
if (NS_FAILED(rv) || !selCon)
return;
nsCOMPtr<nsIPresShell> shell;
PRBool displaySelection;
PRBool isPaginated;
PRBool isSelected;
PRInt16 selectionValue;
selCon->GetDisplaySelection(&selectionValue);
//if greater than hidden then we display some kind of selection
PRBool displaySelection = selectionValue > nsISelectionController::SELECTION_HIDDEN;
nsCOMPtr<nsILineBreaker> lb;
if (NS_FAILED(GetTextInfoForPainting(aPresContext,
aRenderingContext,
getter_AddRefs(shell),
getter_AddRefs(selCon),
displaySelection,
isPaginated,
isSelected,
selectionValue,
getter_AddRefs(lb)))) {
return;
}
// Make enough space to transform
nsAutoTextBuffer paintBuffer;
nsAutoIndexBuffer indexBuffer;
@ -1774,12 +1988,7 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
// transformed when we formatted it, then there's no need to do all
// this and we should just render the text fragment directly. See
// PaintAsciiText()...
nsCOMPtr<nsIDocument> doc;
shell->GetDocument(getter_AddRefs(doc));
if (!doc)
return;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 textLength;
// no need to worry about justification, that's always on the slow path
@ -1788,10 +1997,6 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
PRInt32* ip = indexBuffer.mBuffer;
PRUnichar* text = paintBuffer.mBuffer;
nsFrameState frameState;
PRBool isSelected;
GetFrameState(&frameState);
isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (0 != textLength)
{
@ -1808,12 +2013,13 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
{ //we draw according to selection rules
SelectionDetails *details = nsnull;
nsCOMPtr<nsIFrameSelection> frameSelection;
//get the frameSelection from the selection controller
if (NS_SUCCEEDED(rv) && selCon)
//get the frameSelection from the selection controller
if (selCon)
{
frameSelection = do_QueryInterface(selCon); //this MAY implement
}
//if that failed get it from the pres shell
//if that failed get it from the pres shell
nsresult rv = NS_OK;
if (!frameSelection)
rv = shell->GetFrameSelection(getter_AddRefs(frameSelection));
if (NS_SUCCEEDED(rv) && frameSelection){
@ -1853,7 +2059,7 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING
{
if (iter.CurrentBackGroundColor(currentBKColor))
if (iter.CurrentBackGroundColor(currentBKColor) && !isPaginated)
{//DRAW RECT HERE!!!
aRenderingContext.SetColor(currentBKColor);
aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height);
@ -1863,16 +2069,20 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
else
newWidth =0;
aRenderingContext.SetColor(currentFGColor);
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
if (isPaginated && !iter.IsBeforeOrAfter()) {
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
} else if (!isPaginated) {
aRenderingContext.SetColor(currentFGColor);
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
}
currentX+=newWidth;//increment twips X start
iter.Next();
}
}
else
else if (!isPaginated)
{
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
@ -2298,18 +2508,24 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
TextStyle& aTextStyle,
nscoord dx, nscoord dy)
{
nsCOMPtr<nsIPresShell> shell;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_FAILED(rv) || !shell)
return;
nsCOMPtr<nsISelectionController> selCon;
rv = GetSelectionController(aPresContext, getter_AddRefs(selCon));
if (NS_FAILED(rv) || !selCon)
return;
nsCOMPtr<nsIPresShell> shell;
PRBool displaySelection;
PRBool isPaginated;
PRBool isSelected;
PRInt16 selectionValue;
selCon->GetDisplaySelection(&selectionValue);
PRBool displaySelection = selectionValue > nsISelectionController::SELECTION_HIDDEN;
nsCOMPtr<nsILineBreaker> lb;
if (NS_FAILED(GetTextInfoForPainting(aPresContext,
aRenderingContext,
getter_AddRefs(shell),
getter_AddRefs(selCon),
displaySelection,
isPaginated,
isSelected,
selectionValue,
getter_AddRefs(lb)))) {
return;
}
// Make enough space to transform
@ -2321,13 +2537,6 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
nscoord width = mRect.width;
PRInt32 textLength;
// Transform text from content into renderable form
nsCOMPtr<nsIDocument> doc;
shell->GetDocument(getter_AddRefs(doc));
if (!doc)
return;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 numSpaces;
@ -2337,10 +2546,7 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
PRInt32* ip = indexBuffer.mBuffer;
PRUnichar* text = paintBuffer.mBuffer;
nsFrameState frameState;
PRBool isSelected;
GetFrameState(&frameState);
isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (0 != textLength) {
ComputeExtraJustificationSpacing(aRenderingContext, aTextStyle, text, textLength, numSpaces);
if (!displaySelection || !isSelected) {
@ -2355,6 +2561,7 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
SelectionDetails *details = nsnull;
nsCOMPtr<nsIFrameSelection> frameSelection;
//get the frame selection
nsresult rv = NS_OK;
frameSelection = do_QueryInterface(selCon); //this MAY implement
if (!frameSelection)//if that failed get it from the presshell
rv = shell->GetFrameSelection(getter_AddRefs(frameSelection));
@ -2405,16 +2612,23 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
else
newWidth =0;
aRenderingContext.SetColor(currentFGColor);
RenderString(aRenderingContext,aStyleContext, aTextStyle, currenttext,
currentlength, currentX, dy, width, details);
//increment twips X start but remember to get ready for next draw by reducing current x by letter spacing amount
if (isPaginated && !iter.IsBeforeOrAfter()) {
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
RenderString(aRenderingContext,aStyleContext, aTextStyle, currenttext,
currentlength, currentX, dy, width, details);
} else if (!isPaginated) {
aRenderingContext.SetColor(currentFGColor);
RenderString(aRenderingContext,aStyleContext, aTextStyle, currenttext,
currentlength, currentX, dy, width, details);
}
//increment twips X start but remember to get ready for next draw by reducing current x by letter spacing amount
currentX+=newWidth;// + aTextStyle.mLetterSpacing;
iter.Next();
}
}
else
else if (!isPaginated)
{
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
RenderString(aRenderingContext,aStyleContext, aTextStyle, text,
@ -2440,21 +2654,25 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
nscoord dx, nscoord dy)
{
NS_PRECONDITION(0 == (TEXT_HAS_MULTIBYTE & mState), "text is multi-byte");
nsCOMPtr<nsIPresShell> shell;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_FAILED(rv) || !shell)
return;
nsCOMPtr<nsISelectionController> selCon;
rv = GetSelectionController(aPresContext, getter_AddRefs(selCon));
if (NS_FAILED(rv) || !selCon)
return;
nsCOMPtr<nsIPresShell> shell;
PRBool displaySelection;
PRBool isPaginated;
PRBool isSelected;
PRInt16 selectionValue;
PRBool isSelected;
selCon->GetDisplaySelection(&selectionValue);
PRBool displaySelection = selectionValue > nsISelectionController::SELECTION_HIDDEN;
isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
nsCOMPtr<nsILineBreaker> lb;
if (NS_FAILED(GetTextInfoForPainting(aPresContext,
aRenderingContext,
getter_AddRefs(shell),
getter_AddRefs(selCon),
displaySelection,
isPaginated,
isSelected,
selectionValue,
getter_AddRefs(lb)))) {
return;
}
// Get the text fragment
nsCOMPtr<nsITextContent> tc = do_QueryInterface(mContent);
@ -2475,13 +2693,6 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
}
}
// Construct a text transformer
nsCOMPtr<nsIDocument> doc;
shell->GetDocument(getter_AddRefs(doc));
if (!doc)
return;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull, aPresContext);
// See if we need to transform the text. If the text fragment is ascii and
@ -2557,6 +2768,7 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
nsCOMPtr<nsIFrameSelection> frameSelection;
//get the frame selection
frameSelection = do_QueryInterface(selCon); //this MAY implement
nsresult rv = NS_OK;
if (!frameSelection)//if that failed get it from the presshell
rv = shell->GetFrameSelection(getter_AddRefs(frameSelection));
if (NS_SUCCEEDED(rv) && frameSelection){
@ -2593,7 +2805,7 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING
{
if (iter.CurrentBackGroundColor(currentBKColor))
if (iter.CurrentBackGroundColor(currentBKColor) && !isPaginated)
{//DRAW RECT HERE!!!
aRenderingContext.SetColor(currentBKColor);
aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height);
@ -2602,16 +2814,21 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
}
else
newWidth =0;
aRenderingContext.SetColor(currentFGColor);
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
if (isPaginated && !iter.IsBeforeOrAfter()) {
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
} else if (!isPaginated) {
aRenderingContext.SetColor(currentFGColor);
aRenderingContext.DrawString(currenttext, currentlength, currentX, dy);
}
currentX+=newWidth;//increment twips X start
iter.Next();
}
}
else
else if (!isPaginated)
{
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
@ -4757,7 +4974,11 @@ nsTextFrame::List(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent) cons
// Output the rect and state
fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height);
if (0 != mState) {
fprintf(out, " [state=%08x]", mState);
if (mState & NS_FRAME_SELECTED_CONTENT) {
fprintf(out, " [state=%08x] SELECTED", mState);
} else {
fprintf(out, " [state=%08x]", mState);
}
}
fprintf(out, " sc=%p<\n", mStyleContext);

View File

@ -0,0 +1,42 @@
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Page number formating
## @page_number The current page number
#LOCALIZATION NOTE (pageofpages): Do not translate %ld in the following line.
# Place the word %ld where the page number and number of pages should be
# The first %ld will receive the the page number
pagenumber=%1$d
# Page number formating
## @page_number The current page number
## @page_total The total number of pages
#LOCALIZATION NOTE (pageofpages): Do not translate %ld in the following line.
# Place the word %ld where the page number and number of pages should be
# The first %ld will receive the the page number
# the second %ld will receive the total number of pages
pageofpages=%1$d of %2$d
# Print font
# The name of the font to be used to print the headers and footers
fontname=serif
# Print font size
# The size of the font to be used to print the headers and footers
fontsize=10

View File

@ -2473,6 +2473,10 @@ nsComboboxControlFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
#ifdef NOISY
printf("%p paint layer %d at (%d, %d, %d, %d)\n", this, aWhichLayer,
aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);

View File

@ -156,10 +156,9 @@ nsFieldSetFrame::Paint(nsIPresContext* aPresContext,
{
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
// Paint our background and border
const nsStyleDisplay* disp =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->IsVisible() && mRect.width && mRect.height) {
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) &&
isVisible && mRect.width && mRect.height) {
PRIntn skipSides = GetSkipSides();
const nsStyleColor* color =
(const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);

View File

@ -269,7 +269,8 @@ nsFileControlFrame::MouseClick(nsIDOMEvent* aMouseEvent)
// Get Loc title
nsString title;
nsFormControlHelper::GetLocalizedString("FileUpload", title);
nsFormControlHelper::GetLocalizedString(nsFormControlHelper::GetHTMLPropertiesFileName(),
"FileUpload", title);
nsCOMPtr<nsIFilePicker> filePicker = do_CreateInstance("@mozilla.org/filepicker;1");
if (!filePicker)
@ -658,6 +659,10 @@ nsFileControlFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}

View File

@ -402,6 +402,10 @@ nsFormControlFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
nsresult rv = nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect,
aWhichLayer);

View File

@ -872,12 +872,10 @@ nsFormControlHelper::GetInputElementValue(nsIContent* aContent, nsString* aText,
}
//----------------------------------------------------------------------------------
#define form_properties "chrome://communicator/locale/layout/HtmlForm.properties"
// Return localised string for resource string (e.g. "Submit" -> "Submit Query")
// This code is derived from nsBookmarksService::Init() and cookie_Localize()
nsresult
nsFormControlHelper::GetLocalizedString(char* aKey, nsString& oVal)
nsFormControlHelper::GetLocalizedString(const char * aPropFileName, const char* aKey, nsString& oVal)
{
nsresult rv;
nsCOMPtr<nsIStringBundle> bundle;
@ -887,7 +885,7 @@ nsFormControlHelper::GetLocalizedString(char* aKey, nsString& oVal)
NS_WITH_SERVICE(nsIIOService, pNetService, kIOServiceCID, &rv);
if (NS_SUCCEEDED(rv) && pNetService) {
nsCOMPtr<nsIURI> uri;
rv = pNetService->NewURI(form_properties, nsnull, getter_AddRefs(uri));
rv = pNetService->NewURI(aPropFileName, nsnull, getter_AddRefs(uri));
if (NS_SUCCEEDED(rv) && uri) {
// Create bundle

View File

@ -44,6 +44,10 @@ class nsFormFrame;
#define NS_STRING_TRUE NS_LITERAL_STRING("1")
#define NS_STRING_FALSE NS_LITERAL_STRING("0")
// for localization
#define FORM_PROPERTIES "chrome://communicator/locale/layout/HtmlForm.properties"
/**
* Enumeration of possible mouse states used to detect mouse clicks
*/
@ -174,7 +178,8 @@ public:
static nsresult GetWrapPropertyEnum(nsIContent * aContent, nsHTMLTextWrap& aWrapProp);
// Localization Helper
static nsresult GetLocalizedString(char* aKey, nsString& oVal);
static nsresult GetLocalizedString(const char * aPropFileName, const char* aKey, nsString& oVal);
static const char * GetHTMLPropertiesFileName() { return FORM_PROPERTIES; }
static nsresult GetDisabled(nsIContent* aContent, PRBool* oIsDisabled);
//

View File

@ -475,17 +475,18 @@ nsGfxButtonControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
NS_IMETHODIMP
nsGfxButtonControlFrame::GetDefaultLabel(nsString& aString)
{
const char * propname = nsFormControlHelper::GetHTMLPropertiesFileName();
nsresult rv = NS_OK;
PRInt32 type;
GetType(&type);
if (IsReset(type)) {
rv = nsFormControlHelper::GetLocalizedString("Reset", aString);
rv = nsFormControlHelper::GetLocalizedString(propname, "Reset", aString);
}
else if (IsSubmit(type)) {
rv = nsFormControlHelper::GetLocalizedString("Submit", aString);
rv = nsFormControlHelper::GetLocalizedString(propname, "Submit", aString);
}
else if (IsBrowse(type)) {
rv = nsFormControlHelper::GetLocalizedString("Browse", aString);
rv = nsFormControlHelper::GetLocalizedString(propname, "Browse", aString);
}
else {
aString.AssignWithConversion(" ");

View File

@ -367,10 +367,10 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisible())
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
// Paint the background
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);

View File

@ -314,11 +314,10 @@ nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisible())
return NS_OK;
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
// Paint the background
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);

View File

@ -2014,6 +2014,19 @@ nsGfxTextControlFrame2::Reflow(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
nsGfxTextControlFrame2::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
return nsStackFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
NS_IMETHODIMP
nsGfxTextControlFrame2::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)

View File

@ -69,6 +69,11 @@ public:
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);

View File

@ -475,14 +475,14 @@ nsHTMLButtonControlFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->IsVisible())
{
nsRect rect(0, 0, mRect.width, mRect.height);
mRenderer.PaintButton(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, rect);
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
nsRect rect(0, 0, mRect.width, mRect.height);
mRenderer.PaintButton(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, rect);
#if 0 // old way
PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
@ -498,10 +498,6 @@ nsHTMLButtonControlFrame::Paint(nsIPresContext* aPresContext,
border.SizeTo(0, 0, 0, 0);
spacing->CalcBorderFor(this, border);
nsRect rect;
GetRect(rect);
rect.x = 0;
rect.y = 0;
rect.Deflate(border);
aRenderingContext.PushState();
PRBool clipEmpty;

View File

@ -99,6 +99,19 @@ nsIsIndexFrame::~nsIsIndexFrame()
}
}
NS_IMETHODIMP
nsIsIndexFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
NS_IMETHODIMP
nsIsIndexFrame::UpdatePromptLabel()
{
@ -125,7 +138,8 @@ nsIsIndexFrame::UpdatePromptLabel()
// We can't make any assumption as to what the default would be
// because the value is localized for non-english platforms, thus
// it might not be the string "This is a searchable index. Enter search keywords: "
result = nsFormControlHelper::GetLocalizedString("IsIndexPrompt", prompt);
result = nsFormControlHelper::GetLocalizedString(nsFormControlHelper::GetHTMLPropertiesFileName(),
"IsIndexPrompt", prompt);
}
nsCOMPtr<nsITextContent> text = do_QueryInterface(mTextContent);
result = text->SetText(prompt.GetUnicode(), prompt.Length(), PR_TRUE);

View File

@ -52,6 +52,11 @@ public:
nsIsIndexFrame();
virtual ~nsIsIndexFrame();
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
// XXX Hack so we can squirrel away the pres context pointer for the KeyPress method
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,

View File

@ -457,6 +457,10 @@ nsLabelFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
return nsHTMLContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}

View File

@ -104,6 +104,19 @@ nsLegendFrame::Reflow(nsIPresContext* aPresContext,
}
NS_IMETHODIMP
nsLegendFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
return NS_OK;
}
return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
PRInt32 nsLegendFrame::GetAlign()
{
PRInt32 intValue = NS_STYLE_TEXT_ALIGN_LEFT;

View File

@ -52,6 +52,11 @@ public:
NS_IMETHOD Destroy(nsIPresContext *aPresContext);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
#ifdef NS_DEBUG
NS_IMETHOD GetFrameName(nsString& aResult) const;
#endif

View File

@ -287,9 +287,55 @@ nsListControlFrame::Destroy(nsIPresContext *aPresContext)
return nsScrollFrame::Destroy(aPresContext);
}
//---------------------------------------------------------
//NS_IMPL_ADDREF(nsListControlFrame)
//NS_IMPL_RELEASE(nsListControlFrame)
NS_IMETHODIMP
nsListControlFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
nsIStyleContext* sc = mStyleContext;
const nsStyleDisplay* disp = (const nsStyleDisplay*)sc->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisible()) {
return PR_FALSE;
}
// Start by assuming we are visible and need to be painted
PRBool isVisible = PR_TRUE;
PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated);
if (isPaginated) {
PRBool isRendingSelection;;
aPresContext->IsRenderingOnlySelection(&isRendingSelection);
if (isRendingSelection) {
// Check the quick way first
PRBool isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
// if we aren't selected in the mState we could be a container
// so check to see if we are in the selection range
if (!isSelected) {
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
nsCOMPtr<nsISelectionController> selcon;
selcon = do_QueryInterface(shell);
if (selcon) {
nsCOMPtr<nsISelection> selection;
selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mContent));
selection->ContainsNode(node, PR_TRUE, &isVisible);
} else {
isVisible = PR_FALSE;
}
}
}
}
if (isVisible) {
return nsScrollFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
return NS_OK;
}
//---------------------------------------------------------
// Frames are not refcounted, no need to AddRef

View File

@ -193,6 +193,11 @@ public:
NS_IMETHOD MoveTo(nsIPresContext* aPresContext, nscoord aX, nscoord aY);
NS_IMETHOD Destroy(nsIPresContext *aPresContext);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
// nsIFormControlFrame
NS_IMETHOD GetType(PRInt32* aType) const;
NS_IMETHOD GetName(nsString* aName);

View File

@ -10097,7 +10097,8 @@ GetAlternateTextFor(nsIContent* aContent,
// If there's no "value" attribute either, then use the localized string
// for "Submit" as the alternate text.
if (NS_CONTENT_ATTR_NOT_THERE == rv) {
nsFormControlHelper::GetLocalizedString("Submit", aAltText);
nsFormControlHelper::GetLocalizedString(nsFormControlHelper::GetHTMLPropertiesFileName(),
"Submit", aAltText);
}
}
}

View File

@ -247,6 +247,10 @@ NS_METHOD nsTableCellFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) {
return NS_OK;
}
const nsStyleDisplay* disp =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);

View File

@ -108,6 +108,10 @@ NS_METHOD nsTableColFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) {
return NS_OK;
}
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
nsCompatibility mode;
aPresContext->GetCompatibilityMode(&mode);

View File

@ -434,6 +434,10 @@ NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) {
return NS_OK;
}
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
nsCompatibility mode;
aPresContext->GetCompatibilityMode(&mode);

View File

@ -330,6 +330,10 @@ NS_METHOD nsTableOuterFrame::Paint(nsIPresContext* aPresContext,
aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height);
}
#endif
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) {
return NS_OK;
}
// the remaining code was copied from nsContainerFrame::PaintChildren since
// it only paints the primary child list

View File

@ -513,6 +513,10 @@ NS_METHOD nsTableRowFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) {
return NS_OK;
}
nsresult rv;
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
nsCompatibility mode;

View File

@ -205,6 +205,10 @@ NS_METHOD nsTableRowGroupFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) {
return NS_OK;
}
nsresult rv;
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
nsCompatibility mode;

View File

@ -247,6 +247,10 @@ NS_METHOD nsTableCellFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) {
return NS_OK;
}
const nsStyleDisplay* disp =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);

View File

@ -108,6 +108,10 @@ NS_METHOD nsTableColFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) {
return NS_OK;
}
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
nsCompatibility mode;
aPresContext->GetCompatibilityMode(&mode);

View File

@ -434,6 +434,10 @@ NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) {
return NS_OK;
}
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
nsCompatibility mode;
aPresContext->GetCompatibilityMode(&mode);

View File

@ -330,6 +330,10 @@ NS_METHOD nsTableOuterFrame::Paint(nsIPresContext* aPresContext,
aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height);
}
#endif
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) {
return NS_OK;
}
// the remaining code was copied from nsContainerFrame::PaintChildren since
// it only paints the primary child list

View File

@ -513,6 +513,10 @@ NS_METHOD nsTableRowFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PRBool isVisible;
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) {
return NS_OK;
}
nsresult rv;
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
nsCompatibility mode;

Some files were not shown because too many files have changed in this diff Show More