diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -2996,16 +2996,19 @@ nsDocument::doCreateShell(nsPresContext* } rv = shell->Init(this, aContext, aViewManager, aStyleSet, aCompatMode); NS_ENSURE_SUCCESS(rv, rv); // Note: we don't hold a ref to the shell (it holds a ref to us) NS_ENSURE_TRUE(mPresShells.AppendElementUnlessExists(shell), NS_ERROR_OUT_OF_MEMORY); + + NS_WARN_IF_FALSE(mPresShells.Length() == 1, "More than one presshell!"); + shell.swap(*aInstancePtrResult); return NS_OK; } PRBool nsDocument::DeleteShell(nsIPresShell* aShell) { @@ -7383,16 +7386,28 @@ nsDocument::CloneDocHelper(nsDocument* c // Init document nsresult rv = clone->Init(); NS_ENSURE_SUCCESS(rv, rv); // Set URI/principal clone->nsDocument::SetDocumentURI(nsIDocument::GetDocumentURI()); // Must set the principal first, since SetBaseURI checks it. clone->SetPrincipal(NodePrincipal()); + + nsCOMPtr channel = GetChannel(); + nsCOMPtr loadGroup = GetDocumentLoadGroup(); + if (channel && loadGroup) { + clone->Reset(channel, loadGroup); + } else { + nsIURI* uri = static_cast(this)->GetDocumentURI(); + if (uri) { + clone->ResetToURI(uri, loadGroup, NodePrincipal()); + } + } + clone->mDocumentBaseURI = mDocumentBaseURI; // Set scripting object PRBool hasHadScriptObject = PR_TRUE; nsIScriptGlobalObject* scriptObject = GetScriptHandlingObject(hasHadScriptObject); NS_ENSURE_STATE(scriptObject || !hasHadScriptObject); clone->SetScriptHandlingObject(scriptObject); diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -192,17 +192,16 @@ GK_ATOM(circle, "circle") GK_ATOM(cite, "cite") GK_ATOM(_class, "class") GK_ATOM(classid, "classid") GK_ATOM(clear, "clear") GK_ATOM(click, "click") GK_ATOM(clickcount, "clickcount") GK_ATOM(movetoclick, "movetoclick") GK_ATOM(clip, "clip") -GK_ATOM(clonedTextForPrint, "clonedTextForPrint") GK_ATOM(close, "close") GK_ATOM(closed, "closed") GK_ATOM(closemenu, "closemenu") GK_ATOM(coalesceduplicatearcs, "coalesceduplicatearcs") GK_ATOM(code, "code") GK_ATOM(codebase, "codebase") GK_ATOM(codetype, "codetype") GK_ATOM(col, "col") diff --git a/content/base/src/nsTextFragment.cpp b/content/base/src/nsTextFragment.cpp --- a/content/base/src/nsTextFragment.cpp +++ b/content/base/src/nsTextFragment.cpp @@ -101,17 +101,16 @@ nsTextFragment::Shutdown() sSpaceSharedString[i] = nsnull; sTabSharedString[i] = nsnull; } } nsTextFragment::~nsTextFragment() { ReleaseText(); - MOZ_COUNT_DTOR(nsTextFragment); } void nsTextFragment::ReleaseText() { if (mState.mLength && m1b && mState.mInHeap) { nsMemory::Free(m2b); // m1b == m2b as far as nsMemory is concerned } diff --git a/content/base/src/nsTextFragment.h b/content/base/src/nsTextFragment.h --- a/content/base/src/nsTextFragment.h +++ b/content/base/src/nsTextFragment.h @@ -40,17 +40,16 @@ * node); if only codepoints below 256 are used, the text is stored as * a char*; otherwise the text is stored as a PRUnichar* */ #ifndef nsTextFragment_h___ #define nsTextFragment_h___ #include "nsAString.h" -#include "nsTraceRefcnt.h" class nsString; class nsCString; // XXX should this normalize the code to keep a \u0000 at the end? // XXX nsTextFragmentPool? // XXX these need I18N spankage @@ -84,17 +83,16 @@ public: static void Shutdown(); /** * Default constructor. Initialize the fragment to be empty. */ nsTextFragment() : m1b(nsnull), mAllBits(0) { - MOZ_COUNT_CTOR(nsTextFragment); NS_ASSERTION(sizeof(FragmentBits) == 4, "Bad field packing!"); } ~nsTextFragment(); /** * Change the contents of this fragment to be a copy of the * the argument fragment. diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -11311,18 +11311,17 @@ nsCSSFrameConstructor::RebuildAllStyleDa NS_ASSERTION(!(aExtraHint & nsChangeHint_ReconstructFrame), "Should not reconstruct the root of the frame tree. " "Use ReconstructDocElementHierarchy instead."); mRebuildAllStyleData = PR_FALSE; NS_UpdateHint(aExtraHint, mRebuildAllExtraHint); mRebuildAllExtraHint = nsChangeHint(0); - if (!mPresShell || !mPresShell->GetRootFrame() || - !mPresShell->GetPresContext()->IsDynamic()) + if (!mPresShell || !mPresShell->GetRootFrame()) return; nsAutoScriptBlocker scriptBlocker; // Make sure that the viewmanager will outlive the presshell nsIViewManager::UpdateViewBatch batch(mPresShell->GetViewManager()); // Processing the style changes could cause a flush that propagates to diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -1672,24 +1672,28 @@ DocumentViewerImpl::GetDocument(nsIDocum } nsIPresShell* DocumentViewerImpl::GetPresShell() { if (!GetIsPrintPreview()) { return mPresShell; } - NS_ENSURE_TRUE(mDocument, nsnull); - nsCOMPtr shell; - nsCOMPtr currentShell; - nsPresShellIterator iter(mDocument); - while ((shell = iter.GetNextShell())) { - currentShell.swap(shell); - } - return currentShell.get(); +#if NS_PRINT_PREVIEW + if (mPrintEngine) { + nsIDocument* printDocument = mPrintEngine->GetPrintPreviewDocument(); + if (printDocument) { + nsIPresShell* shell = printDocument->GetPrimaryShell(); + if (shell) { + return shell; + } + } + } +#endif + return mPresShell; } nsPresContext* DocumentViewerImpl::GetPresContext() { if (!GetIsPrintPreview()) { return mPresContext; } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -75,17 +75,16 @@ #include "nsIBaseWindow.h" #include "nsIDocShell.h" #include "nsIDocShellTreeItem.h" #include "nsIWidget.h" #include "gfxMatrix.h" #include "gfxTypes.h" #include "gfxUserFontSet.h" #include "nsTArray.h" -#include "nsTextFragment.h" #ifdef MOZ_SVG #include "nsSVGUtils.h" #include "nsSVGIntegrationUtils.h" #include "nsSVGForeignObjectFrame.h" #include "nsSVGOuterSVGFrame.h" #endif @@ -3217,58 +3216,16 @@ nsLayoutUtils::IsReallyFixedPos(nsIFrame NS_STYLE_POSITION_FIXED, "IsReallyFixedPos called on non-'position:fixed' frame"); nsIAtom *parentType = aFrame->GetParent()->GetType(); return parentType == nsGkAtoms::viewportFrame || parentType == nsGkAtoms::pageContentFrame; } -static void DeleteTextFragment(void* aObject, nsIAtom* aPropertyName, - void* aPropertyValue, void* aData) -{ - delete static_cast(aPropertyValue); -} - -/* static */ nsTextFragment* -nsLayoutUtils::GetTextFragmentForPrinting(const nsIFrame* aFrame) -{ - nsPresContext* presContext = aFrame->PresContext(); - NS_PRECONDITION(!presContext->IsDynamic(), - "Shouldn't call this with dynamic PresContext"); -#ifdef MOZ_SVG - NS_PRECONDITION(aFrame->GetType() == nsGkAtoms::textFrame || - aFrame->GetType() == nsGkAtoms::svgGlyphFrame, - "Wrong frame type!"); -#else - NS_PRECONDITION(aFrame->GetType() == nsGkAtoms::textFrame, - "Wrong frame type!"); -#endif // MOZ_SVG - - nsIContent* content = aFrame->GetContent(); - nsTextFragment* frag = - static_cast(presContext->PropertyTable()-> - GetProperty(content, nsGkAtoms::clonedTextForPrint)); - - if (!frag) { - frag = new nsTextFragment(); - NS_ENSURE_TRUE(frag, nsnull); - *frag = *content->GetText(); - nsresult rv = presContext->PropertyTable()-> - SetProperty(content, nsGkAtoms::clonedTextForPrint, frag, - DeleteTextFragment, nsnull); - if (NS_FAILED(rv)) { - delete frag; - return nsnull; - } - } - - return frag; -} - nsSetAttrRunnable::nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName, const nsAString& aValue) : mContent(aContent), mAttrName(aAttrName), mValue(aValue) { NS_ASSERTION(aContent && aAttrName, "Missing stuff, prepare to crash"); } diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -58,17 +58,16 @@ class nsIFontMetrics; #include "nsStyleSet.h" #include "nsIView.h" #include "nsIFrame.h" #include "nsThreadUtils.h" #include "nsIPresShell.h" #include "gfxPattern.h" class nsBlockFrame; -class nsTextFragment; /** * nsLayoutUtils is a namespace class used for various helper * functions that are useful in multiple places in layout. The goal * is not to define multiple copies of the same static helper. */ class nsLayoutUtils { @@ -986,22 +985,16 @@ public: */ static PRBool IsReallyFixedPos(nsIFrame* aFrame); /** * Indicates if the nsIFrame::GetUsedXXX assertions in nsFrame.cpp should * disabled. */ static PRBool sDisableGetUsedXAssertions; - - /** - * Returns the text fragment, which aFrame should use for printing. - * @param aFrame The nsIFrame object, which uses text fragment data. - */ - static nsTextFragment* GetTextFragmentForPrinting(const nsIFrame* aFrame); }; class nsAutoDisableGetUsedXAssertions { public: nsAutoDisableGetUsedXAssertions() : mOldValue(nsLayoutUtils::sDisableGetUsedXAssertions) { diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -1198,17 +1198,17 @@ nsPresContext::GetDefaultFont(PRUint8 aF break; } return font; } void nsPresContext::SetFullZoom(float aZoom) { - if (!mShell || mFullZoom == aZoom || !IsDynamic()) { + if (!mShell || mFullZoom == aZoom) { return; } // Re-fetch the view manager's window dimensions in case there's a deferred // resize which hasn't affected our mVisibleArea yet nscoord oldWidthAppUnits, oldHeightAppUnits; mShell->GetViewManager()->GetWindowDimensions(&oldWidthAppUnits, &oldHeightAppUnits); float oldWidthDevPixels = oldWidthAppUnits / float(mCurAppUnitsPerDevPixel); float oldHeightDevPixels = oldHeightAppUnits / float(mCurAppUnitsPerDevPixel); diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -761,129 +761,16 @@ FrameArena::FreeFrame(size_t aSize, void } struct nsCallbackEventRequest { nsIReflowCallback* callback; nsCallbackEventRequest* next; }; - -class nsDocumentObserverForNonDynamicPresContext : public nsStubDocumentObserver -{ -public: - nsDocumentObserverForNonDynamicPresContext(nsIDocumentObserver* aBaseObserver) - : mBaseObserver(aBaseObserver) - { - NS_ASSERTION(aBaseObserver, "Null document observer!"); - } - - NS_DECL_ISUPPORTS - - virtual void BeginUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType) - { - mBaseObserver->BeginUpdate(aDocument, aUpdateType); - } - virtual void EndUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType) - { - mBaseObserver->EndUpdate(aDocument, aUpdateType); - } - virtual void BeginLoad(nsIDocument* aDocument) - { - mBaseObserver->BeginLoad(aDocument); - } - virtual void EndLoad(nsIDocument* aDocument) - { - mBaseObserver->EndLoad(aDocument); - } - virtual void ContentStatesChanged(nsIDocument* aDocument, - nsIContent* aContent1, - nsIContent* aContent2, - PRInt32 aStateMask) - { - if ((!aContent1 || IsInRootScrollbar(aContent1)) && - (!aContent2 || IsInRootScrollbar(aContent2))) { - mBaseObserver->ContentStatesChanged(aDocument, aContent1, aContent2, - aStateMask); - } - } - - // nsIMutationObserver - virtual void CharacterDataChanged(nsIDocument* aDocument, - nsIContent* aContent, - CharacterDataChangeInfo* aInfo) - { - if (IsInRootScrollbar(aContent)) { - mBaseObserver->CharacterDataChanged(aDocument, aContent, aInfo); - } - } - virtual void AttributeChanged(nsIDocument* aDocument, - nsIContent* aContent, - PRInt32 aNameSpaceID, - nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) - { - if (IsInRootScrollbar(aContent)) { - mBaseObserver->AttributeChanged(aDocument, aContent, aNameSpaceID, - aAttribute, aModType, aStateMask); - } - } - virtual void ContentAppended(nsIDocument* aDocument, - nsIContent* aContainer, - PRInt32 aNewIndexInContainer) - { - if (IsInRootScrollbar(aContainer)) { - mBaseObserver->ContentAppended(aDocument, aContainer, - aNewIndexInContainer); - } - } - virtual void ContentInserted(nsIDocument* aDocument, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInContainer) - { - if (IsInRootScrollbar(aContainer)) { - mBaseObserver->ContentInserted(aDocument, aContainer, aChild, - aIndexInContainer); - } - } - virtual void ContentRemoved(nsIDocument* aDocument, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInContainer) - { - if (IsInRootScrollbar(aContainer)) { - mBaseObserver->ContentRemoved(aDocument, aContainer, aChild, - aIndexInContainer); - } - } - - PRBool IsInRootScrollbar(nsIContent* aContent) { - if(aContent && aContent->IsInDoc()) { - nsIContent* root = aContent->GetCurrentDoc()->GetRootContent(); - while (aContent && aContent->IsInNativeAnonymousSubtree()) { - nsIContent* parent = aContent->GetParent(); - if (parent == root && aContent->IsNodeOfType(nsINode::eXUL)) { - nsIAtom* tag = aContent->Tag(); - return tag == nsGkAtoms::scrollbar || tag == nsGkAtoms::scrollcorner; - } - aContent = parent; - } - } - return PR_FALSE; - } -protected: - nsCOMPtr mBaseObserver; -}; - -NS_IMPL_ISUPPORTS2(nsDocumentObserverForNonDynamicPresContext, - nsIDocumentObserver, - nsIMutationObserver) - // ---------------------------------------------------------------------------- class nsPresShellEventCB; class PresShell : public nsIPresShell, public nsIViewObserver, public nsStubDocumentObserver, public nsISelectionController, public nsIObserver, public nsSupportsWeakReference { @@ -1306,19 +1193,16 @@ protected: MOZ_TIMER_DECLARE(mFrameCreationWatch) // Used for measuring time spent in frame creation #ifdef MOZ_REFLOW_PERF ReflowCountMgr * mReflowCountMgr; #endif static PRBool sDisableNonTestMouseEvents; - - nsCOMPtr mDocumentObserverForNonDynamicContext; - private: PRBool InZombieDocument(nsIContent *aContent); nsresult RetargetEventToParent(nsGUIEvent* aEvent, nsEventStatus* aEventStatus); //helper funcs for event handling protected: @@ -2379,24 +2263,17 @@ PresShell::RepaintSelection(SelectionTyp return mSelection->RepaintSelection(aType); } // Make shell be a document observer NS_IMETHODIMP PresShell::BeginObservingDocument() { if (mDocument && !mIsDestroying) { - if (mPresContext->IsDynamic()) { - mDocument->AddObserver(this); - } else { - mDocumentObserverForNonDynamicContext = - new nsDocumentObserverForNonDynamicPresContext(this); - NS_ENSURE_TRUE(mDocumentObserverForNonDynamicContext, NS_ERROR_OUT_OF_MEMORY); - mDocument->AddObserver(mDocumentObserverForNonDynamicContext); - } + mDocument->AddObserver(this); if (mIsDocumentGone) { NS_WARNING("Adding a presshell that was disconnected from the document " "as a document observer? Sounds wrong..."); mIsDocumentGone = PR_FALSE; } } return NS_OK; } @@ -2404,20 +2281,17 @@ PresShell::BeginObservingDocument() // Make shell stop being a document observer NS_IMETHODIMP PresShell::EndObservingDocument() { // XXXbz do we need to tell the frame constructor that the document // is gone, perhaps? Except for printing it's NOT gone, sometimes. mIsDocumentGone = PR_TRUE; if (mDocument) { - mDocument->RemoveObserver(mDocumentObserverForNonDynamicContext ? - mDocumentObserverForNonDynamicContext.get() : - this); - mDocumentObserverForNonDynamicContext = nsnull; + mDocument->RemoveObserver(this); } return NS_OK; } #ifdef DEBUG_kipp char* nsPresShell_ReflowStackPointerTop; #endif @@ -3478,20 +3352,16 @@ PresShell::RecreateFramesFor(nsIContent* { NS_ENSURE_TRUE(mPresContext, NS_ERROR_FAILURE); if (!mDidInitialReflow) { // Nothing to do here. In fact, if we proceed and aContent is the // root we will crash. return NS_OK; } - if (!mPresContext->IsDynamic()) { - return NS_OK; - } - // Don't call RecreateFramesForContent since that is not exported and we want // to keep the number of entrypoints down. NS_ASSERTION(mViewManager, "Should have view manager"); nsIViewManager::UpdateViewBatch batch(mViewManager); // Have to make sure that the content notifications are flushed before we // start messing with the frame model; otherwise we can get content doubling. @@ -4895,19 +4765,16 @@ PresShell::ContentRemoved(nsIDocument *a aIndexInContainer, &didReconstruct); VERIFY_STYLE_TREE; } nsresult PresShell::ReconstructFrames(void) { - if (!mPresContext || !mPresContext->IsDynamic()) { - return NS_OK; - } nsAutoScriptBlocker scriptBlocker; mFrameConstructor->BeginUpdate(); nsresult rv = mFrameConstructor->ReconstructDocElementHierarchy(); VERIFY_STYLE_TREE; mFrameConstructor->EndUpdate(); return rv; } diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -54,20 +54,16 @@ #include "nsLineBox.h" #include "gfxFont.h" #include "gfxSkipChars.h" #include "gfxContext.h" class nsTextPaintStyle; class PropertyProvider; -// This bit is set while the frame is registered as a blinking frame or if -// frame is within a non-dynamic PresContext. -#define TEXT_BLINK_ON_OR_PRINTING 0x20000000 - // This state bit is set on frames that have some non-collapsed characters after // reflow #define TEXT_HAS_NONCOLLAPSED_CHARACTERS 0x80000000 class nsTextFrame : public nsFrame { public: friend class nsContinuingTextFrame; @@ -352,27 +348,19 @@ public: struct TrimmedOffsets { PRInt32 mStart; PRInt32 mLength; PRInt32 GetEnd() { return mStart + mLength; } }; TrimmedOffsets GetTrimmedOffsets(const nsTextFragment* aFrag, PRBool aTrimAfter); - const nsTextFragment* GetFragment() const - { - return !(GetStateBits() & TEXT_BLINK_ON_OR_PRINTING) ? - mContent->GetText() : GetFragmentInternal(); - } - protected: virtual ~nsTextFrame(); - const nsTextFragment* GetFragmentInternal() const; - nsIFrame* mNextContinuation; // The key invariant here is that mContentOffset never decreases along // a next-continuation chain. And of course mContentOffset is always <= the // the text node's content length, and the mContentOffset for the first frame // is always 0. Furthermore the text mapped by a frame is determined by // GetContentOffset() and GetContentLength()/GetContentEnd(), which get // the length from the difference between this frame's offset and the next // frame's offset, or the text length if there is no next frame. This means diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp --- a/layout/generic/nsTextFrameThebes.cpp +++ b/layout/generic/nsTextFrameThebes.cpp @@ -158,19 +158,18 @@ // Cache bits for IsEmpty(). // Set this bit if the textframe is known to be only collapsible whitespace. #define TEXT_IS_ONLY_WHITESPACE 0x08000000 // Set this bit if the textframe is known to be not only collapsible whitespace. #define TEXT_ISNOT_ONLY_WHITESPACE 0x10000000 #define TEXT_WHITESPACE_FLAGS 0x18000000 - -// nsTextFrame.h has -// #define TEXT_BLINK_ON_OR_PRINTING 0x20000000 +// This bit is set while the frame is registered as a blinking frame. +#define TEXT_BLINK_ON 0x20000000 // Set when this text frame is mentioned in the userdata for a textrun #define TEXT_IN_TEXTRUN_USER_DATA 0x40000000 // nsTextFrame.h has // #define TEXT_HAS_NONCOLLAPSED_CHARACTERS 0x80000000 /* @@ -477,33 +476,33 @@ nsTextFrameTextRunCache::Init() { void nsTextFrameTextRunCache::Shutdown() { delete gTextRuns; gTextRuns = nsnull; } PRInt32 nsTextFrame::GetContentEnd() const { nsTextFrame* next = static_cast(GetNextContinuation()); - return next ? next->GetContentOffset() : GetFragment()->GetLength(); + return next ? next->GetContentOffset() : mContent->GetText()->GetLength(); } PRInt32 nsTextFrame::GetInFlowContentLength() { #ifdef IBMBIDI nsTextFrame* nextBidi = nsnull; PRInt32 start = -1, end; if (mState & NS_FRAME_IS_BIDI) { nextBidi = static_cast(GetLastInFlow()->GetNextContinuation()); if (nextBidi) { nextBidi->GetOffsets(start, end); return start - mContentOffset; } } #endif //IBMBIDI - return GetFragment()->GetLength() - mContentOffset; + return mContent->TextLength() - mContentOffset; } // Smarter versions of XP_IS_SPACE. // Unicode is really annoying; sometimes a space character isn't whitespace --- // when it combines with another character // So we have several versions of IsSpace for use in different contexts. static PRBool IsSpaceCombiningSequenceTail(const nsTextFragment* aFrag, PRUint32 aPos) @@ -722,17 +721,17 @@ public: // ancestor of the elements containing the characters is the one whose // CSS 'white-space' property governs. So this records the nearest common // ancestor of mStartFrame and the previous text frame, or null if there // was no previous text frame on this line. nsIFrame* mAncestorControllingInitialBreak; PRInt32 GetContentEnd() { return mEndFrame ? mEndFrame->GetContentOffset() - : mStartFrame->GetFragment()->GetLength(); + : mStartFrame->GetContent()->GetText()->GetLength(); } }; class BreakSink : public nsILineBreakSink { public: BreakSink(gfxTextRun* aTextRun, gfxContext* aContext, PRUint32 aOffsetIntoTextRun, PRBool aExistingTextRun) : mTextRun(aTextRun), mContext(aContext), @@ -928,17 +927,17 @@ BuildTextRunsScanner::FindBoundaries(nsI aState->mLastTextFrame = textFrame; } if (aFrame == aState->mStopAtFrame) return FB_STOPPED_AT_STOP_FRAME; if (textFrame) { if (!aState->mSeenSpaceForLineBreakingOnThisLine) { - const nsTextFragment* frag = textFrame->GetFragment(); + const nsTextFragment* frag = textFrame->GetContent()->GetText(); PRUint32 start = textFrame->GetContentOffset(); const void* text = frag->Is2b() ? static_cast(frag->Get2b() + start) : static_cast(frag->Get1b() + start); if (TextContainsLineBreakerWhiteSpace(text, textFrame->GetContentLength(), frag->Is2b())) { aState->mSeenSpaceForLineBreakingOnThisLine = PR_TRUE; if (aState->mSeenTextRunBoundaryOnLaterLine) @@ -1253,17 +1252,17 @@ void BuildTextRunsScanner::FlushLineBrea } mTextRunsToDelete.Clear(); } void BuildTextRunsScanner::AccumulateRunInfo(nsTextFrame* aFrame) { NS_ASSERTION(mMaxTextLength <= mMaxTextLength + aFrame->GetContentLength(), "integer overflow"); mMaxTextLength += aFrame->GetContentLength(); - mDoubleByteText |= aFrame->GetFragment()->Is2b(); + mDoubleByteText |= aFrame->GetContent()->GetText()->Is2b(); mLastFrame = aFrame; mCommonAncestorWithLastFrame = aFrame->GetParent(); MappedFlow* mappedFlow = &mMappedFlows[mMappedFlows.Length() - 1]; NS_ASSERTION(mappedFlow->mStartFrame == aFrame || mappedFlow->GetContentEnd() == aFrame->GetContentOffset(), "Overlapping or discontiguous frames => BAD"); mappedFlow->mEndFrame = static_cast(aFrame->GetNextContinuation()); @@ -1286,17 +1285,17 @@ static nscoord StyleToCoord(const nsStyl } } static PRBool HasTerminalNewline(const nsTextFrame* aFrame) { if (aFrame->GetContentLength() == 0) return PR_FALSE; - const nsTextFragment* frag = aFrame->GetFragment(); + const nsTextFragment* frag = aFrame->GetContent()->GetText(); return frag->CharAt(aFrame->GetContentEnd() - 1) == '\n'; } PRBool BuildTextRunsScanner::ContinueTextRunAcrossFrames(nsTextFrame* aFrame1, nsTextFrame* aFrame2) { if (mBidiEnabled && NS_GET_EMBEDDING_LEVEL(aFrame1) != NS_GET_EMBEDDING_LEVEL(aFrame2)) @@ -1613,17 +1612,17 @@ BuildTextRunsScanner::BuildTextRunForFra } fontStyle = f->GetStyleFont(); if (NS_STYLE_FONT_VARIANT_SMALL_CAPS == fontStyle->mFont.variant) { anySmallcapsStyle = PR_TRUE; } // Figure out what content is included in this flow. nsIContent* content = f->GetContent(); - const nsTextFragment* frag = f->GetFragment(); + const nsTextFragment* frag = content->GetText(); PRInt32 contentStart = mappedFlow->mStartFrame->GetContentOffset(); PRInt32 contentEnd = mappedFlow->GetContentEnd(); PRInt32 contentLength = contentEnd - contentStart; TextRunMappedFlow* newFlow = &userData->mMappedFlows[i]; newFlow->mStartFrame = mappedFlow->mStartFrame; newFlow->mDOMOffsetToBeforeTransformOffset = builder.GetCharCount() - mappedFlow->mStartFrame->GetContentOffset(); @@ -1859,17 +1858,17 @@ HasCompressedLeadingWhitespace(nsTextFra PRInt32 aContentEndOffset, const gfxSkipCharsIterator& aIterator) { if (!aIterator.IsOriginalCharSkipped()) return PR_FALSE; gfxSkipCharsIterator iter = aIterator; PRInt32 frameContentOffset = aFrame->GetContentOffset(); - const nsTextFragment* frag = aFrame->GetFragment(); + const nsTextFragment* frag = aFrame->GetContent()->GetText(); while (frameContentOffset < aContentEndOffset && iter.IsOriginalCharSkipped()) { if (IsTrimmableSpace(frag, frameContentOffset, aStyleText)) return PR_TRUE; ++frameContentOffset; iter.AdvanceOriginal(1); } return PR_FALSE; } @@ -2231,17 +2230,17 @@ public: /** * Use this constructor after the frame has been reflowed and we don't * have other data around. Gets everything from the frame. EnsureTextRun * *must* be called before this!!! */ PropertyProvider(nsTextFrame* aFrame, const gfxSkipCharsIterator& aStart) : mTextRun(aFrame->GetTextRun()), mFontGroup(nsnull), mTextStyle(aFrame->GetStyleText()), - mFrag(aFrame->GetFragment()), + mFrag(aFrame->GetContent()->GetText()), mLineContainer(nsnull), mFrame(aFrame), mStart(aStart), mTempIterator(aStart), mTabWidths(nsnull), mLength(aFrame->GetContentLength()), mWordSpacing(mTextStyle->mWordSpacing), mLetterSpacing(StyleToCoord(mTextStyle->mLetterSpacing)), mJustificationSpacing(0), mHyphenWidth(-1), @@ -3404,21 +3403,16 @@ NS_IMETHODIMP nsTextFrame::GetAccessible NS_IMETHODIMP nsTextFrame::Init(nsIContent* aContent, nsIFrame* aParent, nsIFrame* aPrevInFlow) { NS_ASSERTION(!aPrevInFlow, "Can't be a continuation!"); NS_PRECONDITION(aContent->IsNodeOfType(nsINode::eTEXT), "Bogus content!"); - - if (!PresContext()->IsDynamic()) { - AddStateBits(TEXT_BLINK_ON_OR_PRINTING); - } - // We're not a continuing frame. // mContentOffset = 0; not necessary since we get zeroed out at init return nsFrame::Init(aContent, aParent, aPrevInFlow); } void nsTextFrame::Destroy() { @@ -3486,34 +3480,29 @@ protected: }; NS_IMETHODIMP nsContinuingTextFrame::Init(nsIContent* aContent, nsIFrame* aParent, nsIFrame* aPrevInFlow) { NS_ASSERTION(aPrevInFlow, "Must be a continuation!"); - - if (!PresContext()->IsDynamic()) { - AddStateBits(TEXT_BLINK_ON_OR_PRINTING); - } - // NOTE: bypassing nsTextFrame::Init!!! nsresult rv = nsFrame::Init(aContent, aParent, aPrevInFlow); #ifdef IBMBIDI nsTextFrame* nextContinuation = static_cast(aPrevInFlow->GetNextContinuation()); #endif // IBMBIDI // Hook the frame into the flow SetPrevInFlow(aPrevInFlow); aPrevInFlow->SetNextInFlow(this); nsTextFrame* prev = static_cast(aPrevInFlow); mContentOffset = prev->GetContentOffset() + prev->GetContentLengthHint(); - NS_ASSERTION(mContentOffset < PRInt32(GetFragment()->GetLength()), + NS_ASSERTION(mContentOffset < PRInt32(aContent->GetText()->GetLength()), "Creating ContinuingTextFrame, but there is no more content"); if (prev->GetStyleContext() != GetStyleContext()) { // We're taking part of prev's text, and its style may be different // so clear its textrun which may no longer be valid (and don't set ours) prev->ClearTextRun(); } else { mTextRun = prev->GetTextRun(); } @@ -3683,17 +3672,17 @@ NS_NewTextFrame(nsIPresShell* aPresShell nsIFrame* NS_NewContinuingTextFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { return new (aPresShell) nsContinuingTextFrame(aContext); } nsTextFrame::~nsTextFrame() { - if (0 != (mState & TEXT_BLINK_ON_OR_PRINTING) && PresContext()->IsDynamic()) + if (0 != (mState & TEXT_BLINK_ON)) { nsBlinkTimer::RemoveBlinkFrame(this); } } NS_IMETHODIMP nsTextFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor) @@ -3867,17 +3856,17 @@ nsTextFrame::BuildDisplayList(nsDisplayL const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!IsVisibleForPainting(aBuilder)) return NS_OK; DO_GLOBAL_REFLOW_COUNT_DSP("nsTextFrame"); - if ((0 != (mState & TEXT_BLINK_ON_OR_PRINTING)) && nsBlinkTimer::GetBlinkIsOff() && + if ((0 != (mState & TEXT_BLINK_ON)) && nsBlinkTimer::GetBlinkIsOff() && PresContext()->IsDynamic()) return NS_OK; return aLists.Content()->AppendNewToTop(new (aBuilder) nsDisplayText(this)); } static nsIFrame* GetGeneratedContentOwner(nsIFrame* aFrame, PRBool* aIsBefore) @@ -5050,17 +5039,17 @@ PRBool nsTextFrame::PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset) { NS_ASSERTION(aOffset && *aOffset <= GetContentLength(), "aOffset out of range"); gfxSkipCharsIterator iter = EnsureTextRun(); if (!mTextRun) return PR_FALSE; - TrimmedOffsets trimmed = GetTrimmedOffsets(GetFragment(), PR_TRUE); + TrimmedOffsets trimmed = GetTrimmedOffsets(mContent->GetText(), PR_TRUE); // Check whether there are nonskipped characters in the trimmmed range return iter.ConvertOriginalToSkipped(trimmed.GetEnd()) > iter.ConvertOriginalToSkipped(trimmed.mStart); } /** * This class iterates through the clusters before or after the given * aPosition (which is a content offset). You can test each cluster @@ -5117,17 +5106,17 @@ nsTextFrame::PeekOffsetCharacter(PRBool IsSelectable(&selectable, &selectStyle); if (selectStyle == NS_STYLE_USER_SELECT_ALL) return PR_FALSE; gfxSkipCharsIterator iter = EnsureTextRun(); if (!mTextRun) return PR_FALSE; - TrimmedOffsets trimmed = GetTrimmedOffsets(GetFragment(), PR_FALSE); + TrimmedOffsets trimmed = GetTrimmedOffsets(mContent->GetText(), PR_FALSE); // A negative offset means "end of frame". PRInt32 startOffset = GetContentOffset() + (*aOffset < 0 ? contentLength : *aOffset); if (!aForward) { PRInt32 i; for (i = PR_MIN(trimmed.GetEnd(), startOffset) - 1; i >= trimmed.mStart; --i) { @@ -5232,17 +5221,17 @@ ClusterIterator::ClusterIterator(nsTextF if (!aTextFrame->GetTextRun()) { mDirection = 0; // signal failure return; } mIterator.SetOriginalOffset(aPosition); mCategories = do_GetService(NS_UNICHARCATEGORY_CONTRACTID); - mFrag = aTextFrame->GetFragment(); + mFrag = aTextFrame->GetContent()->GetText(); mTrimmed = aTextFrame->GetTrimmedOffsets(mFrag, PR_TRUE); PRInt32 textOffset = aTextFrame->GetContentOffset(); PRInt32 textLen = aTextFrame->GetContentLength(); if (!mWordBreaks.AppendElements(textLen + 1)) { mDirection = 0; // signal failure return; } @@ -5473,17 +5462,17 @@ nsTextFrame::AddInlineMinWidthForFlow(ns gfxSkipCharsIterator iter = EnsureTextRun(ctx, aData->lineContainer, aData->line, &flowEndInTextRun); if (!mTextRun) return; // Pass null for the line container. This will disable tab spacing, but that's // OK since we can't really handle tabs for intrinsic sizing anyway. const nsStyleText* textStyle = GetStyleText(); - const nsTextFragment* frag = GetFragment(); + const nsTextFragment* frag = mContent->GetText(); PropertyProvider provider(mTextRun, textStyle, frag, this, iter, PR_INT32_MAX, nsnull, 0); PRBool collapseWhitespace = !textStyle->WhiteSpaceIsSignificant(); PRBool preformatNewlines = textStyle->NewlineIsSignificant(); PRBool preformatTabs = textStyle->WhiteSpaceIsSignificant(); gfxFloat tabWidth = -1; PRUint32 start = @@ -5601,17 +5590,17 @@ nsTextFrame::AddInlinePrefWidthForFlow(n EnsureTextRun(ctx, aData->lineContainer, aData->line, &flowEndInTextRun); if (!mTextRun) return; // Pass null for the line container. This will disable tab spacing, but that's // OK since we can't really handle tabs for intrinsic sizing anyway. const nsStyleText* textStyle = GetStyleText(); - const nsTextFragment* frag = GetFragment(); + const nsTextFragment* frag = mContent->GetText(); PropertyProvider provider(mTextRun, textStyle, frag, this, iter, PR_INT32_MAX, nsnull, 0); PRBool collapseWhitespace = !textStyle->WhiteSpaceIsSignificant(); PRBool preformatNewlines = textStyle->NewlineIsSignificant(); PRBool preformatTabs = textStyle->WhiteSpaceIsSignificant(); gfxFloat tabWidth = -1; PRUint32 start = @@ -5839,18 +5828,18 @@ nsTextFrame::Reflow(nsPresContext* aReflowState.availableWidth, aReflowState.availableHeight); #endif ///////////////////////////////////////////////////////////////////// // Set up flags and clear out state ///////////////////////////////////////////////////////////////////// // Clear out the reflow state flags in mState (without destroying - // the TEXT_BLINK_ON_OR_PRINTING bit). We also clear the whitespace flags - // because this can change whether the frame maps whitespace-only text or not. + // the TEXT_BLINK_ON bit). We also clear the whitespace flags because this + // can change whether the frame maps whitespace-only text or not. RemoveStateBits(TEXT_REFLOW_FLAGS | TEXT_WHITESPACE_FLAGS); // Temporarily map all possible content while we construct our new textrun. // so that when doing reflow our styles prevail over any part of the // textrun we look at. Note that next-in-flows may be mapping the same // content; gfxTextRun construction logic will ensure that we take priority. PRInt32 maxContentLength = GetInFlowContentLength(); @@ -5862,39 +5851,39 @@ nsTextFrame::Reflow(nsPresContext* ClearMetrics(aMetrics); aStatus = NS_FRAME_COMPLETE; return NS_OK; } nsLineLayout& lineLayout = *aReflowState.mLineLayout; if (aReflowState.mFlags.mBlinks) { - if (0 == (mState & TEXT_BLINK_ON_OR_PRINTING) && PresContext()->IsDynamic()) { - mState |= TEXT_BLINK_ON_OR_PRINTING; + if (0 == (mState & TEXT_BLINK_ON)) { + mState |= TEXT_BLINK_ON; nsBlinkTimer::AddBlinkFrame(aPresContext, this); } } else { - if (0 != (mState & TEXT_BLINK_ON_OR_PRINTING) && PresContext()->IsDynamic()) { - mState &= ~TEXT_BLINK_ON_OR_PRINTING; + if (0 != (mState & TEXT_BLINK_ON)) { + mState &= ~TEXT_BLINK_ON; nsBlinkTimer::RemoveBlinkFrame(this); } } const nsStyleText* textStyle = GetStyleText(); PRBool atStartOfLine = lineLayout.LineIsEmpty(); if (atStartOfLine) { AddStateBits(TEXT_START_OF_LINE); } PRUint32 flowEndInTextRun; nsIFrame* lineContainer = lineLayout.GetLineContainerFrame(); gfxContext* ctx = aReflowState.rendContext->ThebesContext(); - const nsTextFragment* frag = GetFragment(); + const nsTextFragment* frag = mContent->GetText(); // DOM offsets of the text range we need to measure, after trimming // whitespace, restricting to first-letter, and restricting preformatted text // to nearest newline PRInt32 length = maxContentLength; PRInt32 offset = GetContentOffset(); // Restrict preformatted text to the nearest newline @@ -6294,17 +6283,17 @@ nsTextFrame::TrimTrailingWhiteSpace(nsIR return result; gfxContext* ctx = aRC->ThebesContext(); gfxSkipCharsIterator start = EnsureTextRun(ctx); NS_ENSURE_TRUE(mTextRun, result); PRUint32 trimmedStart = start.GetSkippedOffset(); - const nsTextFragment* frag = GetFragment(); + const nsTextFragment* frag = mContent->GetText(); TrimmedOffsets trimmed = GetTrimmedOffsets(frag, PR_TRUE); gfxSkipCharsIterator trimmedEndIter = start; const nsStyleText* textStyle = GetStyleText(); gfxFloat delta = 0; PRUint32 trimmedEnd = trimmedEndIter.ConvertOriginalToSkipped(trimmed.GetEnd()); if (GetStateBits() & TEXT_TRIMMED_TRAILING_WHITESPACE) { // We pre-trimmed this frame, so the last character is justifiable @@ -6431,17 +6420,17 @@ nsresult nsTextFrame::GetRenderedText(ns gfxSkipChars* aSkipChars, gfxSkipCharsIterator* aSkipIter, PRUint32 aSkippedStartOffset, PRUint32 aSkippedMaxLength) { // The handling of aSkippedStartOffset and aSkippedMaxLength could be more efficient... gfxSkipCharsBuilder skipCharsBuilder; nsTextFrame* textFrame; - const nsTextFragment* textFrag = GetFragment(); + const nsTextFragment* textFrag = mContent->GetText(); PRUint32 keptCharsLength = 0; PRUint32 validCharsLength = 0; // Build skipChars and copy text, for each text frame in this continuation block for (textFrame = this; textFrame; textFrame = static_cast(textFrame->GetNextContinuation())) { // For each text frame continuation in this block ... @@ -6497,17 +6486,17 @@ nsresult nsTextFrame::GetRenderedText(ns } #ifdef DEBUG // Translate the mapped content into a string that's printable void nsTextFrame::ToCString(nsCString& aBuf, PRInt32* aTotalContentLength) const { // Get the frames text content - const nsTextFragment* frag = GetFragment(); + const nsTextFragment* frag = mContent->GetText(); if (!frag) { return; } // Compute the total length of the text content. *aTotalContentLength = frag->GetLength(); PRInt32 contentLength = GetContentLength(); @@ -6557,17 +6546,17 @@ nsTextFrame::IsEmpty() if (mState & TEXT_ISNOT_ONLY_WHITESPACE) { return PR_FALSE; } if (mState & TEXT_IS_ONLY_WHITESPACE) { return PR_TRUE; } - PRBool isEmpty = IsAllWhitespace(GetFragment(), + PRBool isEmpty = IsAllWhitespace(mContent->GetText(), textStyle->mWhiteSpace != NS_STYLE_WHITESPACE_PRE_LINE); mState |= (isEmpty ? TEXT_IS_ONLY_WHITESPACE : TEXT_ISNOT_ONLY_WHITESPACE); return isEmpty; } #ifdef DEBUG NS_IMETHODIMP nsTextFrame::GetFrameName(nsAString& aResult) const @@ -6694,15 +6683,8 @@ nsTextFrame::HasTerminalNewline() const return ::HasTerminalNewline(this); } PRBool nsTextFrame::IsAtEndOfLine() const { return (GetStateBits() & TEXT_END_OF_LINE) != 0; } - -const nsTextFragment* -nsTextFrame::GetFragmentInternal() const -{ - return PresContext()->IsDynamic() ? mContent->GetText() : - nsLayoutUtils::GetTextFragmentForPrinting(this); -} diff --git a/layout/printing/nsPrintEngine.cpp b/layout/printing/nsPrintEngine.cpp --- a/layout/printing/nsPrintEngine.cpp +++ b/layout/printing/nsPrintEngine.cpp @@ -1153,20 +1153,20 @@ nsPrintEngine::BuildDocTree(nsIDocShellT nsCOMPtr viewer; childAsShell->GetContentViewer(getter_AddRefs(viewer)); if (viewer) { nsCOMPtr viewerFile(do_QueryInterface(viewer)); if (viewerFile) { nsCOMPtr childDocShell(do_QueryInterface(child)); nsCOMPtr childNode(do_QueryInterface(child)); nsPrintObject * po = new nsPrintObject(); + po->mParent = aPO; nsresult rv = po->Init(childDocShell); if (NS_FAILED(rv)) NS_NOTREACHED("Init failed?"); - po->mParent = aPO; aPO->mKids.AppendElement(po); aDocList->AppendElement(po); BuildDocTree(childNode, aDocList, po); } } } } } @@ -1218,17 +1218,27 @@ nsPrintEngine::MapContentToWebShells(nsP nsPrintObject* aPO) { NS_ASSERTION(aRootPO, "Pointer is null!"); NS_ASSERTION(aPO, "Pointer is null!"); // Recursively walk the content from the root item // XXX Would be faster to enumerate the subdocuments, although right now // nsIDocument doesn't expose quite what would be needed. - nsIContent *rootContent = aPO->mDocument->GetRootContent(); + + nsCOMPtr viewer; + aPO->mDocShell->GetContentViewer(getter_AddRefs(viewer)); + if (!viewer) return; + + nsCOMPtr domDoc; + viewer->GetDOMDocument(getter_AddRefs(domDoc)); + nsCOMPtr doc = do_QueryInterface(domDoc); + if (!doc) return; + + nsIContent *rootContent = doc->GetRootContent(); if (rootContent) { MapContentForPO(aPO, rootContent); } else { NS_WARNING("Null root content on (sub)document."); } // Continue recursively walking the chilren of this PO for (PRUint32 i=0;imKids.Length();i++) { @@ -1302,26 +1312,26 @@ nsPrintEngine::MapContentForPO(nsPrintOb nsCOMPtr container = subDoc->GetContainer(); nsCOMPtr docShell(do_QueryInterface(container)); if (docShell) { nsPrintObject * po = nsnull; PRInt32 cnt = aPO->mKids.Length(); for (PRInt32 i=0;imKids.ElementAt(i); - if (kid->mDocument == subDoc) { + if (kid->mOriginalDocument == subDoc) { po = kid; break; } } // XXX If a subdocument has no onscreen presentation, there will be no PO // This is even if there should be a print presentation if (po) { - po->mContent = aContent; + //po->mContent = aContent; nsCOMPtr frame(do_QueryInterface(aContent)); // "frame" elements not in a frameset context should be treated // as iframes if (frame && po->mParent->mFrameType == eFrameSet) { po->mFrameType = eFrame; } else { // Assume something iframe-like, i.e. iframe, object, or embed @@ -1864,18 +1874,21 @@ nsPrintEngine::ReflowPrintObject(nsPrint if (aPO->mParent && aPO->mParent->IsPrintable()) { if (aPO->mParent->mPresShell) { frame = aPO->mParent->mPresShell->FrameManager()-> GetPrimaryFrameFor(aPO->mContent, -1); } // Without a frame, this document can't be displayed; therefore, there is no // point to reflowing it - if (!frame) + if (!frame) { + static int c = 0; + printf("No frame %i\n\n", ++c); return NS_OK; + } adjSize = frame->GetContentRect().Size(); documentIsTopLevel = PR_FALSE; // presshell exists because parent is printable } else { nscoord pageWidth, pageHeight; mPrt->mPrintDC->GetDeviceSurfaceDimensions(pageWidth, pageHeight); #if defined(XP_UNIX) && !defined(XP_MACOSX) diff --git a/layout/printing/nsPrintEngine.h b/layout/printing/nsPrintEngine.h --- a/layout/printing/nsPrintEngine.h +++ b/layout/printing/nsPrintEngine.h @@ -192,16 +192,21 @@ public: static PRBool HasFramesetChild(nsIContent* aContent); PRBool CheckBeforeDestroy(); nsresult Cancelled(); nsIWidget* GetPrintPreviewWindow() {return mPrtPreview->mPrintObject->mWindow;} + nsIDocument* GetPrintPreviewDocument() + { + return mPrtPreview ? mPrtPreview->mPrintObject->mDocument : nsnull; + } + nsIViewManager* GetPrintPreviewViewManager() {return mPrtPreview->mPrintObject->mViewManager;} float GetPrintPreviewScale() { return mPrtPreview->mPrintObject-> mPresContext->GetPrintPreviewScale(); } static nsIPresShell* GetPresShellFor(nsIDocShell* aDocShell); // These calls also update the DocViewer diff --git a/layout/printing/nsPrintObject.cpp b/layout/printing/nsPrintObject.cpp --- a/layout/printing/nsPrintObject.cpp +++ b/layout/printing/nsPrintObject.cpp @@ -69,23 +69,55 @@ nsPrintObject::Init(nsIDocShell* aDocShe mDocShell = aDocShell; NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); nsresult rv; nsCOMPtr viewer; rv = mDocShell->GetContentViewer(getter_AddRefs(viewer)); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr doc; - viewer->GetDOMDocument(getter_AddRefs(doc)); + nsCOMPtr domDoc; + viewer->GetDOMDocument(getter_AddRefs(domDoc)); NS_ENSURE_SUCCESS(rv, rv); - - mDocument = do_QueryInterface(doc); - NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE); + nsCOMPtr doc = do_QueryInterface(domDoc); + NS_ENSURE_STATE(doc); + + nsCOMPtr clonedNode; + rv = domDoc->CloneNode(PR_TRUE, getter_AddRefs(clonedNode)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr clonedDoc = do_QueryInterface(clonedNode); + NS_ENSURE_STATE(clonedDoc); + clonedDoc->SetScriptGlobalObject(doc->GetScriptGlobalObject()); + + PRInt32 sheetsCount = doc->GetNumberOfStyleSheets(); + for (PRInt32 i = 0; i < sheetsCount; ++i) { + nsCOMPtr sheet = + do_QueryInterface(doc->GetStyleSheetAt(i)); + if (sheet) { + PRBool applicable = PR_TRUE; + sheet->GetApplicable(applicable); + if (applicable) { + nsCOMPtr clonedSheet; + sheet->Clone(nsnull, nsnull, clonedDoc, nsnull, + getter_AddRefs(clonedSheet)); + NS_WARN_IF_FALSE(clonedSheet, "Cloning didn't work!"); + if (clonedSheet) { + clonedDoc->AddStyleSheet(clonedSheet); + } + } + } + } + + static int c = 0; + printf("Did clone a document %i\n\n", ++c); + + mDocument = clonedDoc; + mOriginalDocument = doc; return NS_OK; } //------------------------------------------------------------------ // Resets PO by destroying the presentation void nsPrintObject::DestroyPresentation() { diff --git a/layout/printing/nsPrintObject.h b/layout/printing/nsPrintObject.h --- a/layout/printing/nsPrintObject.h +++ b/layout/printing/nsPrintObject.h @@ -65,23 +65,24 @@ public: nsresult Init(nsIDocShell* aDocShell); PRBool IsPrintable() { return !mDontPrint; } void DestroyPresentation(); // Data Members nsCOMPtr mDocShell; nsCOMPtr mDocument; + nsCOMPtr mOriginalDocument; nsCOMPtr mPresContext; nsCOMPtr mPresShell; nsCOMPtr mViewManager; nsCOMPtr mWindow; - nsIContent* mContent; + nsCOMPtr mContent; PrintObjectType mFrameType; nsTArray mKids; nsPrintObject* mParent; PRPackedBool mHasBeenPrinted; PRPackedBool mDontPrint; PRPackedBool mPrintAsIs; PRPackedBool mSharedPresShell; diff --git a/layout/svg/base/src/nsSVGGlyphFrame.cpp b/layout/svg/base/src/nsSVGGlyphFrame.cpp --- a/layout/svg/base/src/nsSVGGlyphFrame.cpp +++ b/layout/svg/base/src/nsSVGGlyphFrame.cpp @@ -49,17 +49,16 @@ #include "nsSVGPathElement.h" #include "nsSVGPoint.h" #include "nsSVGRect.h" #include "nsDOMError.h" #include "gfxContext.h" #include "gfxMatrix.h" #include "gfxPlatform.h" #include "gfxTextRunWordCache.h" -#include "nsTextFrame.h" struct CharacterPosition { gfxPoint pos; gfxFloat angle; PRBool draw; }; /** @@ -295,20 +294,16 @@ nsSVGGlyphFrame::Init(nsIContent* aConte nsISVGTextContentMetrics *metrics = do_QueryFrame(ancestorFrame); NS_ASSERTION(metrics, "trying to construct an SVGGlyphFrame for an invalid container"); NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT), "trying to construct an SVGGlyphFrame for wrong content element"); #endif /* DEBUG */ - if (!PresContext()->IsDynamic()) { - AddStateBits(NS_STATE_SVG_PRINTING); - } - return nsSVGGlyphFrameBase::Init(aContent, aParent, aPrevInFlow); } nsIAtom * nsSVGGlyphFrame::GetType() const { return nsGkAtoms::svgGlyphFrame; } @@ -631,17 +626,17 @@ nsSVGGlyphFrame::GetCanvasTM(nsIDOMSVGMa //---------------------------------------------------------------------- // nsSVGGlyphFrame methods: PRBool nsSVGGlyphFrame::GetCharacterData(nsAString & aCharacterData) { nsAutoString characterData; - GetFragment()->AppendTo(characterData); + mContent->AppendTextTo(characterData); if (mWhitespaceHandling & COMPRESS_WHITESPACE) { PRBool trimLeadingWhitespace, trimTrailingWhitespace; trimLeadingWhitespace = ((mWhitespaceHandling & TRIM_LEADING_WHITESPACE) != 0); trimTrailingWhitespace = ((mWhitespaceHandling & TRIM_TRAILING_WHITESPACE) != 0); characterData.CompressWhitespace(trimLeadingWhitespace, trimTrailingWhitespace); } else { @@ -783,17 +778,17 @@ nsSVGGlyphFrame::GetHighlight(PRUint32 * NS_ERROR("nsSVGGlyphFrame::GetHighlight() called by renderer when there is no highlight"); return NS_ERROR_FAILURE; } nsPresContext *presContext = PresContext(); // The selection ranges are relative to the uncompressed text in // the content element. We'll need the text fragment: - const nsTextFragment* fragment = GetFragment(); + const nsTextFragment *fragment = mContent->GetText(); NS_ASSERTION(fragment, "no text"); // get the selection details SelectionDetails *details = nsnull; { nsCOMPtr frameSelection; { nsCOMPtr controller; @@ -1101,17 +1096,17 @@ nsSVGGlyphFrame::IsAbsolutelyPositioned( //---------------------------------------------------------------------- // nsISVGGlyphFragmentNode interface: NS_IMETHODIMP_(PRUint32) nsSVGGlyphFrame::GetNumberOfChars() { if (mWhitespaceHandling == PRESERVE_WHITESPACE) - return GetFragment()->GetLength(); + return mContent->TextLength(); nsAutoString text; GetCharacterData(text); return text.Length(); } NS_IMETHODIMP_(float) nsSVGGlyphFrame::GetComputedTextLength() diff --git a/layout/svg/base/src/nsSVGGlyphFrame.h b/layout/svg/base/src/nsSVGGlyphFrame.h --- a/layout/svg/base/src/nsSVGGlyphFrame.h +++ b/layout/svg/base/src/nsSVGGlyphFrame.h @@ -208,21 +208,16 @@ protected: gfxContext *aContext); void NotifyGlyphMetricsChange(); PRBool ContainsPoint(const nsPoint &aPoint); PRBool GetGlobalTransform(gfxMatrix *aMatrix); void SetupGlobalTransform(gfxContext *aContext); nsresult GetHighlight(PRUint32 *charnum, PRUint32 *nchars, nscolor *foreground, nscolor *background); - const nsTextFragment* GetFragment() const - { - return !(GetStateBits() & NS_STATE_SVG_PRINTING) ? - mContent->GetText() : nsLayoutUtils::GetTextFragmentForPrinting(this); - } // Owning pointer, must call gfxTextRunWordCache::RemoveTextRun before deleting gfxTextRun *mTextRun; gfxPoint mPosition; PRUint8 mWhitespaceHandling; }; #endif diff --git a/layout/svg/base/src/nsSVGUtils.h b/layout/svg/base/src/nsSVGUtils.h --- a/layout/svg/base/src/nsSVGUtils.h +++ b/layout/svg/base/src/nsSVGUtils.h @@ -89,19 +89,16 @@ class nsSVGGeometryFrame; #define NS_STATE_SVG_DIRTY 0x00200000 /* are we the child of a non-display container? */ #define NS_STATE_SVG_NONDISPLAY_CHILD 0x00400000 #define NS_STATE_SVG_PROPAGATE_TRANSFORM 0x00800000 -// nsSVGGlyphFrame uses this when the frame is within a non-dynamic PresContext. -#define NS_STATE_SVG_PRINTING 0x01000000 - /** * Byte offsets of channels in a native packed gfxColor or cairo image surface. */ #ifdef IS_BIG_ENDIAN #define GFX_ARGB32_OFFSET_A 0 #define GFX_ARGB32_OFFSET_R 1 #define GFX_ARGB32_OFFSET_G 2 #define GFX_ARGB32_OFFSET_B 3