зеркало из https://github.com/mozilla/gecko-dev.git
Bug 425265, r=roc, sr=bz
This commit is contained in:
Родитель
7aac9e4432
Коммит
c10a9dfb86
|
@ -196,6 +196,7 @@ GK_ATOM(clear, "clear")
|
|||
GK_ATOM(click, "click")
|
||||
GK_ATOM(clickcount, "clickcount")
|
||||
GK_ATOM(clip, "clip")
|
||||
GK_ATOM(clonedTextForPrint, "clonedTextForPrint")
|
||||
GK_ATOM(close, "close")
|
||||
GK_ATOM(closed, "closed")
|
||||
GK_ATOM(closemenu, "closemenu")
|
||||
|
|
|
@ -106,6 +106,7 @@ nsTextFragment::Shutdown()
|
|||
nsTextFragment::~nsTextFragment()
|
||||
{
|
||||
ReleaseText();
|
||||
MOZ_COUNT_DTOR(nsTextFragment);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#define nsTextFragment_h___
|
||||
|
||||
#include "nsAString.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
class nsString;
|
||||
class nsCString;
|
||||
|
||||
|
@ -88,6 +89,7 @@ public:
|
|||
nsTextFragment()
|
||||
: m1b(nsnull), mAllBits(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsTextFragment);
|
||||
NS_ASSERTION(sizeof(FragmentBits) == 4, "Bad field packing!");
|
||||
}
|
||||
|
||||
|
|
|
@ -12330,7 +12330,8 @@ nsCSSFrameConstructor::RebuildAllStyleData(nsChangeHint aExtraHint)
|
|||
NS_UpdateHint(aExtraHint, mRebuildAllExtraHint);
|
||||
mRebuildAllExtraHint = nsChangeHint(0);
|
||||
|
||||
if (!mPresShell || !mPresShell->GetRootFrame())
|
||||
if (!mPresShell || !mPresShell->GetRootFrame() ||
|
||||
!mPresShell->GetPresContext()->IsDynamic())
|
||||
return;
|
||||
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
|
|
@ -456,6 +456,8 @@ protected:
|
|||
unsigned mClosingWhilePrinting : 1;
|
||||
|
||||
#if NS_PRINT_PREVIEW
|
||||
unsigned mPrintPreviewZoomed : 1;
|
||||
|
||||
// These data members support delayed printing when the document is loading
|
||||
unsigned mPrintIsPending : 1;
|
||||
unsigned mPrintDocIsFullyLoaded : 1;
|
||||
|
@ -463,6 +465,8 @@ protected:
|
|||
nsCOMPtr<nsIWebProgressListener> mCachedPrintWebProgressListner;
|
||||
|
||||
nsCOMPtr<nsPrintEngine> mPrintEngine;
|
||||
float mOriginalPrintPreviewScale;
|
||||
float mPrintPreviewZoom;
|
||||
#endif // NS_PRINT_PREVIEW
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
@ -536,6 +540,9 @@ void DocumentViewerImpl::PrepareToStartLoad()
|
|||
DocumentViewerImpl::DocumentViewerImpl()
|
||||
: mTextZoom(1.0), mPageZoom(1.0),
|
||||
mIsSticky(PR_TRUE),
|
||||
#ifdef NS_PRINT_PREVIEW
|
||||
mPrintPreviewZoom(1.0),
|
||||
#endif
|
||||
mHintCharsetSource(kCharsetUninitialized)
|
||||
{
|
||||
PrepareToStartLoad();
|
||||
|
@ -2722,10 +2729,12 @@ SetExtResourceFullZoom(nsIDocument* aDocument, void* aClosure)
|
|||
NS_IMETHODIMP
|
||||
DocumentViewerImpl::SetTextZoom(float aTextZoom)
|
||||
{
|
||||
if (!GetIsPrintPreview()) {
|
||||
mTextZoom = aTextZoom;
|
||||
if (GetIsPrintPreview()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mTextZoom = aTextZoom;
|
||||
|
||||
nsIViewManager::UpdateViewBatch batch(GetViewManager());
|
||||
|
||||
// Set the text zoom on all children of mContainer (even if our zoom didn't
|
||||
|
@ -2761,9 +2770,39 @@ DocumentViewerImpl::GetTextZoom(float* aTextZoom)
|
|||
NS_IMETHODIMP
|
||||
DocumentViewerImpl::SetFullZoom(float aFullZoom)
|
||||
{
|
||||
if (!GetIsPrintPreview()) {
|
||||
mPageZoom = aFullZoom;
|
||||
#ifdef NS_PRINT_PREVIEW
|
||||
if (GetIsPrintPreview()) {
|
||||
nsPresContext* pc = GetPresContext();
|
||||
NS_ENSURE_TRUE(pc, NS_OK);
|
||||
nsCOMPtr<nsIPresShell> shell = pc->GetPresShell();
|
||||
NS_ENSURE_TRUE(shell, NS_OK);
|
||||
|
||||
nsIViewManager::UpdateViewBatch batch(pc->GetViewManager());
|
||||
if (!mPrintPreviewZoomed) {
|
||||
mOriginalPrintPreviewScale = pc->GetPrintPreviewScale();
|
||||
mPrintPreviewZoomed = PR_TRUE;
|
||||
}
|
||||
|
||||
mPrintPreviewZoom = aFullZoom;
|
||||
pc->SetPrintPreviewScale(aFullZoom * mOriginalPrintPreviewScale);
|
||||
nsIPageSequenceFrame* pf = nsnull;
|
||||
shell->GetPageSequenceFrame(&pf);
|
||||
if (pf) {
|
||||
nsIFrame* f = do_QueryFrame(pf);
|
||||
shell->FrameNeedsReflow(f, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
|
||||
nsIFrame* rootFrame = shell->GetRootFrame();
|
||||
if (rootFrame) {
|
||||
nsRect rect(nsPoint(0, 0), rootFrame->GetSize());
|
||||
rootFrame->Invalidate(rect);
|
||||
}
|
||||
batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
mPageZoom = aFullZoom;
|
||||
|
||||
nsIViewManager::UpdateViewBatch batch(GetViewManager());
|
||||
|
||||
|
@ -2787,6 +2826,12 @@ NS_IMETHODIMP
|
|||
DocumentViewerImpl::GetFullZoom(float* aFullZoom)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aFullZoom);
|
||||
#ifdef NS_PRINT_PREVIEW
|
||||
if (GetIsPrintPreview()) {
|
||||
*aFullZoom = mPrintPreviewZoom;
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
// Check the prescontext first because it might have a temporary
|
||||
// setting for print-preview
|
||||
nsPresContext* pc = GetPresContext();
|
||||
|
@ -3622,6 +3667,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings,
|
|||
}
|
||||
|
||||
rv = mPrintEngine->PrintPreview(aPrintSettings, aChildDOMWin, aWebProgressListener);
|
||||
mPrintPreviewZoomed = PR_FALSE;
|
||||
if (NS_FAILED(rv)) {
|
||||
OnDonePrinting();
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
#include "gfxTypes.h"
|
||||
#include "gfxUserFontSet.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsTextFragment.h"
|
||||
|
||||
#ifdef MOZ_SVG
|
||||
#include "nsSVGUtils.h"
|
||||
|
@ -3175,6 +3176,45 @@ nsLayoutUtils::IsReallyFixedPos(nsIFrame* aFrame)
|
|||
parentType == nsGkAtoms::pageContentFrame;
|
||||
}
|
||||
|
||||
static void DeleteTextFragment(void* aObject, nsIAtom* aPropertyName,
|
||||
void* aPropertyValue, void* aData)
|
||||
{
|
||||
delete static_cast<nsTextFragment*>(aPropertyValue);
|
||||
}
|
||||
|
||||
|
||||
/* static */ nsresult
|
||||
nsLayoutUtils::InitTextRunContainerForPrinting(nsIContent* aContent,
|
||||
nsIFrame* aFrame,
|
||||
nsFrameState aBits)
|
||||
{
|
||||
NS_PRECONDITION(aFrame->GetType() == nsGkAtoms::textFrame ||
|
||||
aFrame->GetType() == nsGkAtoms::svgGlyphFrame,
|
||||
"Wrong frame type!");
|
||||
|
||||
nsPresContext* presContext = aFrame->PresContext();
|
||||
if (presContext->IsDynamic()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!presContext->PropertyTable()->
|
||||
GetProperty(aContent, nsGkAtoms::clonedTextForPrint)) {
|
||||
nsTextFragment* frag = new nsTextFragment();
|
||||
NS_ENSURE_TRUE(frag, NS_ERROR_OUT_OF_MEMORY);
|
||||
*frag = *aContent->GetText();
|
||||
nsresult rv = presContext->PropertyTable()->
|
||||
SetProperty(aContent, nsGkAtoms::clonedTextForPrint, frag,
|
||||
DeleteTextFragment, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete frag;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
aFrame->AddStateBits(aBits);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsSetAttrRunnable::nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName,
|
||||
const nsAString& aValue)
|
||||
: mContent(aContent),
|
||||
|
|
|
@ -958,6 +958,21 @@ public:
|
|||
* disabled.
|
||||
*/
|
||||
static PRBool sDisableGetUsedXAssertions;
|
||||
|
||||
/**
|
||||
* Initilizes text run container for printing. Does *nothing* if
|
||||
* aFrame->PresContext() is dynamic.
|
||||
* @param aContainerContent The nsIContent object from which aFrame gets data
|
||||
* for text run creation.
|
||||
* @param aFrame The nsIFrame object which is being initialized.
|
||||
* @param aBits Frame type dependent bits which will be set to
|
||||
* aFrame to mark that PresContext has a text fragment
|
||||
* property called nsGkAtoms::clonedTextForPrint for
|
||||
* aContent.
|
||||
*/
|
||||
static nsresult InitTextRunContainerForPrinting(nsIContent* aContainerContent,
|
||||
nsIFrame* aFrame,
|
||||
nsFrameState aBits);
|
||||
};
|
||||
|
||||
class nsAutoDisableGetUsedXAssertions
|
||||
|
|
|
@ -1205,7 +1205,7 @@ nsPresContext::GetDefaultFont(PRUint8 aFontID) const
|
|||
void
|
||||
nsPresContext::SetFullZoom(float aZoom)
|
||||
{
|
||||
if (!mShell || mFullZoom == aZoom) {
|
||||
if (!mShell || mFullZoom == aZoom || !IsDynamic()) {
|
||||
return;
|
||||
}
|
||||
// Re-fetch the view manager's window dimensions in case there's a deferred
|
||||
|
|
|
@ -766,6 +766,119 @@ struct nsCallbackEventRequest
|
|||
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<nsIDocumentObserver> mBaseObserver;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsDocumentObserverForNonDynamicPresContext,
|
||||
nsIDocumentObserver,
|
||||
nsIMutationObserver)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
class nsPresShellEventCB;
|
||||
|
||||
|
@ -1198,6 +1311,9 @@ protected:
|
|||
|
||||
static PRBool sDisableNonTestMouseEvents;
|
||||
|
||||
|
||||
nsCOMPtr<nsIDocumentObserver> mDocumentObserverForNonDynamicContext;
|
||||
|
||||
private:
|
||||
|
||||
PRBool InZombieDocument(nsIContent *aContent);
|
||||
|
@ -2268,7 +2384,14 @@ NS_IMETHODIMP
|
|||
PresShell::BeginObservingDocument()
|
||||
{
|
||||
if (mDocument && !mIsDestroying) {
|
||||
mDocument->AddObserver(this);
|
||||
if (mPresContext->IsDynamic()) {
|
||||
mDocument->AddObserver(this);
|
||||
} else {
|
||||
mDocumentObserverForNonDynamicContext =
|
||||
new nsDocumentObserverForNonDynamicPresContext(this);
|
||||
NS_ENSURE_TRUE(mDocumentObserverForNonDynamicContext, NS_ERROR_OUT_OF_MEMORY);
|
||||
mDocument->AddObserver(mDocumentObserverForNonDynamicContext);
|
||||
}
|
||||
if (mIsDocumentGone) {
|
||||
NS_WARNING("Adding a presshell that was disconnected from the document "
|
||||
"as a document observer? Sounds wrong...");
|
||||
|
@ -2286,7 +2409,10 @@ PresShell::EndObservingDocument()
|
|||
// is gone, perhaps? Except for printing it's NOT gone, sometimes.
|
||||
mIsDocumentGone = PR_TRUE;
|
||||
if (mDocument) {
|
||||
mDocument->RemoveObserver(this);
|
||||
mDocument->RemoveObserver(mDocumentObserverForNonDynamicContext ?
|
||||
mDocumentObserverForNonDynamicContext.get() :
|
||||
this);
|
||||
mDocumentObserverForNonDynamicContext = nsnull;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3357,6 +3483,10 @@ PresShell::RecreateFramesFor(nsIContent* aContent)
|
|||
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.
|
||||
|
||||
|
@ -4770,6 +4900,9 @@ PresShell::ContentRemoved(nsIDocument *aDocument,
|
|||
nsresult
|
||||
PresShell::ReconstructFrames(void)
|
||||
{
|
||||
if (!mPresContext || !mPresContext->IsDynamic()) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
mFrameConstructor->BeginUpdate();
|
||||
nsresult rv = mFrameConstructor->ReconstructDocElementHierarchy();
|
||||
|
|
|
@ -172,8 +172,8 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext,
|
|||
// it right in paginated mode.
|
||||
if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
|
||||
// Return our desired size
|
||||
aDesiredSize.height = mSize.height;
|
||||
aDesiredSize.width = mSize.width;
|
||||
aDesiredSize.height = mSize.height * PresContext()->GetPrintPreviewScale();
|
||||
aDesiredSize.width = mSize.width * PresContext()->GetPrintPreviewScale();
|
||||
aDesiredSize.mOverflowArea = nsRect(0, 0, aDesiredSize.width,
|
||||
aDesiredSize.height);
|
||||
FinishAndStoreOverflow(&aDesiredSize);
|
||||
|
@ -355,8 +355,9 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext,
|
|||
// Return our desired size
|
||||
// Adjustr the reflow size by PrintPreviewScale so the scrollbars end up the
|
||||
// correct size
|
||||
nscoord w = (x + availSize.width + deadSpaceGap);
|
||||
aDesiredSize.height = y * PresContext()->GetPrintPreviewScale(); // includes page heights and dead space
|
||||
aDesiredSize.width = (x + availSize.width + deadSpaceGap) * PresContext()->GetPrintPreviewScale();
|
||||
aDesiredSize.width = w * PresContext()->GetPrintPreviewScale();
|
||||
|
||||
aDesiredSize.mOverflowArea = nsRect(0, 0, aDesiredSize.width,
|
||||
aDesiredSize.height);
|
||||
|
@ -364,8 +365,8 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext,
|
|||
|
||||
// cache the size so we can set the desired size
|
||||
// for the other reflows that happen
|
||||
mSize.width = aDesiredSize.width;
|
||||
mSize.height = aDesiredSize.height;
|
||||
mSize.width = w;
|
||||
mSize.height = y;
|
||||
|
||||
NS_FRAME_TRACE_REFLOW_OUT("nsSimplePageSequeceFrame::Reflow", aStatus);
|
||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
||||
|
|
|
@ -59,6 +59,10 @@
|
|||
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
|
||||
|
@ -353,9 +357,17 @@ public:
|
|||
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
|
||||
|
|
|
@ -163,8 +163,9 @@
|
|||
#define TEXT_ISNOT_ONLY_WHITESPACE 0x10000000
|
||||
|
||||
#define TEXT_WHITESPACE_FLAGS 0x18000000
|
||||
// This bit is set while the frame is registered as a blinking frame.
|
||||
#define TEXT_BLINK_ON 0x20000000
|
||||
|
||||
// nsTextFrame.h has
|
||||
// #define TEXT_BLINK_ON_OR_PRINTING 0x20000000
|
||||
|
||||
// Set when this text frame is mentioned in the userdata for a textrun
|
||||
#define TEXT_IN_TEXTRUN_USER_DATA 0x40000000
|
||||
|
@ -453,7 +454,7 @@ nsTextFrameTextRunCache::Shutdown() {
|
|||
|
||||
PRInt32 nsTextFrame::GetContentEnd() const {
|
||||
nsTextFrame* next = static_cast<nsTextFrame*>(GetNextContinuation());
|
||||
return next ? next->GetContentOffset() : mContent->GetText()->GetLength();
|
||||
return next ? next->GetContentOffset() : GetFragment()->GetLength();
|
||||
}
|
||||
|
||||
PRInt32 nsTextFrame::GetInFlowContentLength() {
|
||||
|
@ -698,7 +699,7 @@ public:
|
|||
|
||||
PRInt32 GetContentEnd() {
|
||||
return mEndFrame ? mEndFrame->GetContentOffset()
|
||||
: mStartFrame->GetContent()->GetText()->GetLength();
|
||||
: mStartFrame->GetFragment()->GetLength();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -904,7 +905,7 @@ BuildTextRunsScanner::FindBoundaries(nsIFrame* aFrame, FindBoundaryState* aState
|
|||
|
||||
if (textFrame) {
|
||||
if (!aState->mSeenSpaceForLineBreakingOnThisLine) {
|
||||
const nsTextFragment* frag = textFrame->GetContent()->GetText();
|
||||
const nsTextFragment* frag = textFrame->GetFragment();
|
||||
PRUint32 start = textFrame->GetContentOffset();
|
||||
const void* text = frag->Is2b()
|
||||
? static_cast<const void*>(frag->Get2b() + start)
|
||||
|
@ -1229,7 +1230,7 @@ void BuildTextRunsScanner::AccumulateRunInfo(nsTextFrame* aFrame)
|
|||
{
|
||||
NS_ASSERTION(mMaxTextLength <= mMaxTextLength + aFrame->GetContentLength(), "integer overflow");
|
||||
mMaxTextLength += aFrame->GetContentLength();
|
||||
mDoubleByteText |= aFrame->GetContent()->GetText()->Is2b();
|
||||
mDoubleByteText |= aFrame->GetFragment()->Is2b();
|
||||
mLastFrame = aFrame;
|
||||
mCommonAncestorWithLastFrame = aFrame->GetParent();
|
||||
|
||||
|
@ -1262,7 +1263,7 @@ HasTerminalNewline(const nsTextFrame* aFrame)
|
|||
{
|
||||
if (aFrame->GetContentLength() == 0)
|
||||
return PR_FALSE;
|
||||
const nsTextFragment* frag = aFrame->GetContent()->GetText();
|
||||
const nsTextFragment* frag = aFrame->GetFragment();
|
||||
return frag->CharAt(aFrame->GetContentEnd() - 1) == '\n';
|
||||
}
|
||||
|
||||
|
@ -1589,7 +1590,7 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
|
|||
|
||||
// Figure out what content is included in this flow.
|
||||
nsIContent* content = f->GetContent();
|
||||
const nsTextFragment* frag = content->GetText();
|
||||
const nsTextFragment* frag = f->GetFragment();
|
||||
PRInt32 contentStart = mappedFlow->mStartFrame->GetContentOffset();
|
||||
PRInt32 contentEnd = mappedFlow->GetContentEnd();
|
||||
PRInt32 contentLength = contentEnd - contentStart;
|
||||
|
@ -1835,7 +1836,7 @@ HasCompressedLeadingWhitespace(nsTextFrame* aFrame, const nsStyleText* aStyleTex
|
|||
|
||||
gfxSkipCharsIterator iter = aIterator;
|
||||
PRInt32 frameContentOffset = aFrame->GetContentOffset();
|
||||
const nsTextFragment* frag = aFrame->GetContent()->GetText();
|
||||
const nsTextFragment* frag = aFrame->GetFragment();
|
||||
while (frameContentOffset < aContentEndOffset && iter.IsOriginalCharSkipped()) {
|
||||
if (IsTrimmableSpace(frag, frameContentOffset, aStyleText))
|
||||
return PR_TRUE;
|
||||
|
@ -2207,7 +2208,7 @@ public:
|
|||
PropertyProvider(nsTextFrame* aFrame, const gfxSkipCharsIterator& aStart)
|
||||
: mTextRun(aFrame->GetTextRun()), mFontGroup(nsnull),
|
||||
mTextStyle(aFrame->GetStyleText()),
|
||||
mFrag(aFrame->GetContent()->GetText()),
|
||||
mFrag(aFrame->GetFragment()),
|
||||
mLineContainer(nsnull),
|
||||
mFrame(aFrame), mStart(aStart), mTempIterator(aStart),
|
||||
mTabWidths(nsnull),
|
||||
|
@ -3331,6 +3332,12 @@ nsTextFrame::Init(nsIContent* aContent,
|
|||
NS_ASSERTION(!aPrevInFlow, "Can't be a continuation!");
|
||||
NS_PRECONDITION(aContent->IsNodeOfType(nsINode::eTEXT),
|
||||
"Bogus content!");
|
||||
|
||||
nsresult rv = nsLayoutUtils::InitTextRunContainerForPrinting(aContent,
|
||||
this,
|
||||
TEXT_BLINK_ON_OR_PRINTING);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We're not a continuing frame.
|
||||
// mContentOffset = 0; not necessary since we get zeroed out at init
|
||||
return nsFrame::Init(aContent, aParent, aPrevInFlow);
|
||||
|
@ -3408,8 +3415,14 @@ nsContinuingTextFrame::Init(nsIContent* aContent,
|
|||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
NS_ASSERTION(aPrevInFlow, "Must be a continuation!");
|
||||
|
||||
nsresult rv = nsLayoutUtils::InitTextRunContainerForPrinting(aContent,
|
||||
this,
|
||||
TEXT_BLINK_ON_OR_PRINTING);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// NOTE: bypassing nsTextFrame::Init!!!
|
||||
nsresult rv = nsFrame::Init(aContent, aParent, aPrevInFlow);
|
||||
rv = nsFrame::Init(aContent, aParent, aPrevInFlow);
|
||||
|
||||
#ifdef IBMBIDI
|
||||
nsTextFrame* nextContinuation =
|
||||
|
@ -3420,7 +3433,7 @@ nsContinuingTextFrame::Init(nsIContent* aContent,
|
|||
aPrevInFlow->SetNextInFlow(this);
|
||||
nsTextFrame* prev = static_cast<nsTextFrame*>(aPrevInFlow);
|
||||
mContentOffset = prev->GetContentOffset() + prev->GetContentLengthHint();
|
||||
NS_ASSERTION(mContentOffset < PRInt32(aContent->GetText()->GetLength()),
|
||||
NS_ASSERTION(mContentOffset < PRInt32(GetFragment()->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
|
||||
|
@ -3600,7 +3613,7 @@ NS_NewContinuingTextFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
|||
|
||||
nsTextFrame::~nsTextFrame()
|
||||
{
|
||||
if (0 != (mState & TEXT_BLINK_ON))
|
||||
if (0 != (mState & TEXT_BLINK_ON_OR_PRINTING) && PresContext()->IsDynamic())
|
||||
{
|
||||
nsBlinkTimer::RemoveBlinkFrame(this);
|
||||
}
|
||||
|
@ -3784,7 +3797,7 @@ nsTextFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
DO_GLOBAL_REFLOW_COUNT_DSP("nsTextFrame");
|
||||
|
||||
if ((0 != (mState & TEXT_BLINK_ON)) && nsBlinkTimer::GetBlinkIsOff() &&
|
||||
if ((0 != (mState & TEXT_BLINK_ON_OR_PRINTING)) && nsBlinkTimer::GetBlinkIsOff() &&
|
||||
PresContext()->IsDynamic())
|
||||
return NS_OK;
|
||||
|
||||
|
@ -4961,7 +4974,7 @@ nsTextFrame::PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset)
|
|||
if (!mTextRun)
|
||||
return PR_FALSE;
|
||||
|
||||
TrimmedOffsets trimmed = GetTrimmedOffsets(mContent->GetText(), PR_TRUE);
|
||||
TrimmedOffsets trimmed = GetTrimmedOffsets(GetFragment(), PR_TRUE);
|
||||
// Check whether there are nonskipped characters in the trimmmed range
|
||||
return iter.ConvertOriginalToSkipped(trimmed.GetEnd()) >
|
||||
iter.ConvertOriginalToSkipped(trimmed.mStart);
|
||||
|
@ -5028,7 +5041,7 @@ nsTextFrame::PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset)
|
|||
if (!mTextRun)
|
||||
return PR_FALSE;
|
||||
|
||||
TrimmedOffsets trimmed = GetTrimmedOffsets(mContent->GetText(), PR_FALSE);
|
||||
TrimmedOffsets trimmed = GetTrimmedOffsets(GetFragment(), PR_FALSE);
|
||||
|
||||
// A negative offset means "end of frame".
|
||||
PRInt32 startOffset = GetContentOffset() + (*aOffset < 0 ? contentLength : *aOffset);
|
||||
|
@ -5143,7 +5156,7 @@ ClusterIterator::ClusterIterator(nsTextFrame* aTextFrame, PRInt32 aPosition,
|
|||
|
||||
mCategories = do_GetService(NS_UNICHARCATEGORY_CONTRACTID);
|
||||
|
||||
mFrag = aTextFrame->GetContent()->GetText();
|
||||
mFrag = aTextFrame->GetFragment();
|
||||
mTrimmed = aTextFrame->GetTrimmedOffsets(mFrag, PR_TRUE);
|
||||
|
||||
PRInt32 textOffset = aTextFrame->GetContentOffset();
|
||||
|
@ -5384,7 +5397,7 @@ nsTextFrame::AddInlineMinWidthForFlow(nsIRenderingContext *aRenderingContext,
|
|||
// 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 = mContent->GetText();
|
||||
const nsTextFragment* frag = GetFragment();
|
||||
PropertyProvider provider(mTextRun, textStyle, frag, this,
|
||||
iter, PR_INT32_MAX, nsnull, 0);
|
||||
|
||||
|
@ -5512,7 +5525,7 @@ nsTextFrame::AddInlinePrefWidthForFlow(nsIRenderingContext *aRenderingContext,
|
|||
// OK since we can't really handle tabs for intrinsic sizing anyway.
|
||||
|
||||
const nsStyleText* textStyle = GetStyleText();
|
||||
const nsTextFragment* frag = mContent->GetText();
|
||||
const nsTextFragment* frag = GetFragment();
|
||||
PropertyProvider provider(mTextRun, textStyle, frag, this,
|
||||
iter, PR_INT32_MAX, nsnull, 0);
|
||||
|
||||
|
@ -5750,8 +5763,8 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Clear out the reflow state flags in mState (without destroying
|
||||
// the TEXT_BLINK_ON bit). We also clear the whitespace flags because this
|
||||
// can change whether the frame maps whitespace-only text or not.
|
||||
// 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.
|
||||
RemoveStateBits(TEXT_REFLOW_FLAGS | TEXT_WHITESPACE_FLAGS);
|
||||
|
||||
// Temporarily map all possible content while we construct our new textrun.
|
||||
|
@ -5773,14 +5786,14 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
|||
nsLineLayout& lineLayout = *aReflowState.mLineLayout;
|
||||
|
||||
if (aReflowState.mFlags.mBlinks) {
|
||||
if (0 == (mState & TEXT_BLINK_ON)) {
|
||||
mState |= TEXT_BLINK_ON;
|
||||
if (0 == (mState & TEXT_BLINK_ON_OR_PRINTING) && PresContext()->IsDynamic()) {
|
||||
mState |= TEXT_BLINK_ON_OR_PRINTING;
|
||||
nsBlinkTimer::AddBlinkFrame(aPresContext, this);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (0 != (mState & TEXT_BLINK_ON)) {
|
||||
mState &= ~TEXT_BLINK_ON;
|
||||
if (0 != (mState & TEXT_BLINK_ON_OR_PRINTING) && PresContext()->IsDynamic()) {
|
||||
mState &= ~TEXT_BLINK_ON_OR_PRINTING;
|
||||
nsBlinkTimer::RemoveBlinkFrame(this);
|
||||
}
|
||||
}
|
||||
|
@ -5795,7 +5808,7 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
|||
PRUint32 flowEndInTextRun;
|
||||
nsIFrame* lineContainer = lineLayout.GetLineContainerFrame();
|
||||
gfxContext* ctx = aReflowState.rendContext->ThebesContext();
|
||||
const nsTextFragment* frag = mContent->GetText();
|
||||
const nsTextFragment* frag = GetFragment();
|
||||
|
||||
// DOM offsets of the text range we need to measure, after trimming
|
||||
// whitespace, restricting to first-letter, and restricting preformatted text
|
||||
|
@ -6205,7 +6218,7 @@ nsTextFrame::TrimTrailingWhiteSpace(nsIRenderingContext* aRC)
|
|||
|
||||
PRUint32 trimmedStart = start.GetSkippedOffset();
|
||||
|
||||
const nsTextFragment* frag = mContent->GetText();
|
||||
const nsTextFragment* frag = GetFragment();
|
||||
TrimmedOffsets trimmed = GetTrimmedOffsets(frag, PR_TRUE);
|
||||
gfxSkipCharsIterator trimmedEndIter = start;
|
||||
const nsStyleText* textStyle = GetStyleText();
|
||||
|
@ -6342,7 +6355,7 @@ nsresult nsTextFrame::GetRenderedText(nsAString* aAppendToString,
|
|||
// The handling of aSkippedStartOffset and aSkippedMaxLength could be more efficient...
|
||||
gfxSkipCharsBuilder skipCharsBuilder;
|
||||
nsTextFrame* textFrame;
|
||||
const nsTextFragment* textFrag = mContent->GetText();
|
||||
const nsTextFragment* textFrag = GetFragment();
|
||||
PRUint32 keptCharsLength = 0;
|
||||
PRUint32 validCharsLength = 0;
|
||||
|
||||
|
@ -6408,7 +6421,7 @@ void
|
|||
nsTextFrame::ToCString(nsCString& aBuf, PRInt32* aTotalContentLength) const
|
||||
{
|
||||
// Get the frames text content
|
||||
const nsTextFragment* frag = mContent->GetText();
|
||||
const nsTextFragment* frag = GetFragment();
|
||||
if (!frag) {
|
||||
return;
|
||||
}
|
||||
|
@ -6468,7 +6481,7 @@ nsTextFrame::IsEmpty()
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool isEmpty = IsAllWhitespace(mContent->GetText(),
|
||||
PRBool isEmpty = IsAllWhitespace(GetFragment(),
|
||||
textStyle->mWhiteSpace != NS_STYLE_WHITESPACE_PRE_LINE);
|
||||
mState |= (isEmpty ? TEXT_IS_ONLY_WHITESPACE : TEXT_ISNOT_ONLY_WHITESPACE);
|
||||
return isEmpty;
|
||||
|
@ -6605,3 +6618,11 @@ nsTextFrame::IsAtEndOfLine() const
|
|||
{
|
||||
return (GetStateBits() & TEXT_END_OF_LINE) != 0;
|
||||
}
|
||||
|
||||
const nsTextFragment*
|
||||
nsTextFrame::GetFragmentInternal() const
|
||||
{
|
||||
return PresContext()->IsDynamic() ? mContent->GetText() :
|
||||
static_cast<const nsTextFragment*>(PresContext()->PropertyTable()->
|
||||
GetProperty(mContent, nsGkAtoms::clonedTextForPrint));
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "gfxMatrix.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxTextRunWordCache.h"
|
||||
#include "nsTextFrame.h"
|
||||
|
||||
struct CharacterPosition {
|
||||
gfxPoint pos;
|
||||
|
@ -298,6 +299,11 @@ nsSVGGlyphFrame::Init(nsIContent* aContent,
|
|||
NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT),
|
||||
"trying to construct an SVGGlyphFrame for wrong content element");
|
||||
|
||||
nsresult rv = nsLayoutUtils::InitTextRunContainerForPrinting(aContent,
|
||||
this,
|
||||
NS_STATE_SVG_PRINTING);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return nsSVGGlyphFrameBase::Init(aContent, aParent, aPrevInFlow);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
@ -610,7 +616,7 @@ PRBool
|
|||
nsSVGGlyphFrame::GetCharacterData(nsAString & aCharacterData)
|
||||
{
|
||||
nsAutoString characterData;
|
||||
mContent->AppendTextTo(characterData);
|
||||
GetFragment()->AppendTo(characterData);
|
||||
|
||||
if (mWhitespaceHandling & COMPRESS_WHITESPACE) {
|
||||
PRBool trimLeadingWhitespace, trimTrailingWhitespace;
|
||||
|
@ -762,7 +768,7 @@ nsSVGGlyphFrame::GetHighlight(PRUint32 *charnum, PRUint32 *nchars,
|
|||
|
||||
// The selection ranges are relative to the uncompressed text in
|
||||
// the content element. We'll need the text fragment:
|
||||
const nsTextFragment *fragment = mContent->GetText();
|
||||
const nsTextFragment* fragment = GetFragment();
|
||||
NS_ASSERTION(fragment, "no text");
|
||||
|
||||
// get the selection details
|
||||
|
@ -1080,7 +1086,7 @@ NS_IMETHODIMP_(PRUint32)
|
|||
nsSVGGlyphFrame::GetNumberOfChars()
|
||||
{
|
||||
if (mWhitespaceHandling == PRESERVE_WHITESPACE)
|
||||
return mContent->TextLength();
|
||||
return GetFragment()->GetLength();
|
||||
|
||||
nsAutoString text;
|
||||
GetCharacterData(text);
|
||||
|
|
|
@ -215,6 +215,13 @@ protected:
|
|||
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() :
|
||||
static_cast<const nsTextFragment*>(PresContext()->PropertyTable()->
|
||||
GetProperty(mContent, nsGkAtoms::clonedTextForPrint));
|
||||
}
|
||||
|
||||
// Owning pointer, must call gfxTextRunWordCache::RemoveTextRun before deleting
|
||||
gfxTextRun *mTextRun;
|
||||
|
|
|
@ -93,6 +93,9 @@ class nsISVGChildFrame;
|
|||
|
||||
#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.
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче