зеркало из https://github.com/mozilla/pjs.git
Bug 319786 - implement xml:space handling. r=tor,sr=roc
This commit is contained in:
Родитель
e1f7f22ade
Коммит
6fc4b12f9c
|
@ -86,6 +86,12 @@ nsSVGForeignObjectFrame::nsSVGForeignObjectFrame(nsStyleContext* aContext)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsSVGForeignObjectFrame::Destroy()
|
||||||
|
{
|
||||||
|
nsSVGUtils::StyleEffects(this);
|
||||||
|
nsSVGForeignObjectFrameBase::Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// nsISupports methods
|
// nsISupports methods
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ class nsSVGForeignObjectFrame : public nsSVGForeignObjectFrameBase,
|
||||||
NS_NewSVGForeignObjectFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
NS_NewSVGForeignObjectFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||||
protected:
|
protected:
|
||||||
nsSVGForeignObjectFrame(nsStyleContext* aContext);
|
nsSVGForeignObjectFrame(nsStyleContext* aContext);
|
||||||
|
virtual void Destroy();
|
||||||
|
|
||||||
// nsISupports interface:
|
// nsISupports interface:
|
||||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||||
|
|
|
@ -72,6 +72,12 @@ NS_NewSVGGFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext*
|
||||||
return new (aPresShell) nsSVGGFrame(aContext);
|
return new (aPresShell) nsSVGGFrame(aContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsSVGGFrame::Destroy()
|
||||||
|
{
|
||||||
|
nsSVGUtils::StyleEffects(this);
|
||||||
|
nsSVGGFrameBase::Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
nsIAtom *
|
nsIAtom *
|
||||||
nsSVGGFrame::GetType() const
|
nsSVGGFrame::GetType() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,6 +54,7 @@ class nsSVGGFrame : public nsSVGGFrameBase,
|
||||||
public:
|
public:
|
||||||
nsSVGGFrame(nsStyleContext* aContext) :
|
nsSVGGFrame(nsStyleContext* aContext) :
|
||||||
nsSVGGFrameBase(aContext), mPropagateTransform(PR_TRUE) {}
|
nsSVGGFrameBase(aContext), mPropagateTransform(PR_TRUE) {}
|
||||||
|
virtual void Destroy();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the "type" of the frame
|
* Get the "type" of the frame
|
||||||
|
|
|
@ -536,6 +536,15 @@ nsSVGGlyphFrame::GetCharacterData(nsAString & aCharacterData)
|
||||||
trimTrailingWhitespace = ((mWhitespaceHandling & TRIM_TRAILING_WHITESPACE) != 0);
|
trimTrailingWhitespace = ((mWhitespaceHandling & TRIM_TRAILING_WHITESPACE) != 0);
|
||||||
characterData.CompressWhitespace(trimLeadingWhitespace,
|
characterData.CompressWhitespace(trimLeadingWhitespace,
|
||||||
trimTrailingWhitespace);
|
trimTrailingWhitespace);
|
||||||
|
} else {
|
||||||
|
nsAString::iterator start, end;
|
||||||
|
characterData.BeginWriting(start);
|
||||||
|
characterData.EndWriting(end);
|
||||||
|
while (start != end) {
|
||||||
|
if (NS_IsAsciiWhitespace(*start))
|
||||||
|
*start = ' ';
|
||||||
|
++start;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
aCharacterData = characterData;
|
aCharacterData = characterData;
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ class nsSVGInnerSVGFrame : public nsSVGInnerSVGFrameBase,
|
||||||
NS_NewSVGInnerSVGFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
NS_NewSVGInnerSVGFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||||
protected:
|
protected:
|
||||||
nsSVGInnerSVGFrame(nsStyleContext* aContext);
|
nsSVGInnerSVGFrame(nsStyleContext* aContext);
|
||||||
|
virtual void Destroy();
|
||||||
|
|
||||||
// nsISupports interface:
|
// nsISupports interface:
|
||||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||||
|
@ -138,6 +139,12 @@ nsSVGInnerSVGFrame::nsSVGInnerSVGFrame(nsStyleContext* aContext) :
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsSVGInnerSVGFrame::Destroy()
|
||||||
|
{
|
||||||
|
nsSVGUtils::StyleEffects(this);
|
||||||
|
nsSVGInnerSVGFrameBase::Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsSVGInnerSVGFrame::UpdateCoordCtx()
|
nsSVGInnerSVGFrame::UpdateCoordCtx()
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,18 +40,104 @@
|
||||||
#include "nsIDOMSVGSVGElement.h"
|
#include "nsIDOMSVGSVGElement.h"
|
||||||
#include "nsISVGRenderer.h"
|
#include "nsISVGRenderer.h"
|
||||||
#include "nsSVGSVGElement.h"
|
#include "nsSVGSVGElement.h"
|
||||||
|
#include "nsSVGTextFrame.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
#include "nsIViewManager.h"
|
#include "nsIViewManager.h"
|
||||||
#include "nsReflowPath.h"
|
#include "nsReflowPath.h"
|
||||||
#include "nsSVGRect.h"
|
#include "nsSVGRect.h"
|
||||||
#include "nsDisplayList.h"
|
#include "nsDisplayList.h"
|
||||||
#include "nsISVGRendererCanvas.h"
|
#include "nsISVGRendererCanvas.h"
|
||||||
|
#include "nsStubMutationObserver.h"
|
||||||
|
|
||||||
#if defined(DEBUG) && defined(SVG_DEBUG_PRINTING)
|
#if defined(DEBUG) && defined(SVG_DEBUG_PRINTING)
|
||||||
#include "nsIDeviceContext.h"
|
#include "nsIDeviceContext.h"
|
||||||
#include "nsTransform2D.h"
|
#include "nsTransform2D.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class nsSVGMutationObserver : public nsStubMutationObserver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// nsIMutationObserver interface
|
||||||
|
void AttributeChanged(nsIDocument *aDocument,
|
||||||
|
nsIContent *aContent,
|
||||||
|
PRInt32 aNameSpaceID,
|
||||||
|
nsIAtom *aAttribute,
|
||||||
|
PRInt32 aModType);
|
||||||
|
|
||||||
|
// nsISupports interface:
|
||||||
|
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||||
|
private:
|
||||||
|
NS_IMETHOD_(nsrefcnt) AddRef() { return 1; }
|
||||||
|
NS_IMETHOD_(nsrefcnt) Release() { return 1; }
|
||||||
|
|
||||||
|
static void UpdateTextFragmentTrees(nsIFrame *aFrame);
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// nsISupports methods
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN(nsSVGMutationObserver)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
|
||||||
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
static nsSVGMutationObserver sSVGMutationObserver;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// nsIMutationObserver methods
|
||||||
|
|
||||||
|
void
|
||||||
|
nsSVGMutationObserver::AttributeChanged(nsIDocument *aDocument,
|
||||||
|
nsIContent *aContent,
|
||||||
|
PRInt32 aNameSpaceID,
|
||||||
|
nsIAtom *aAttribute,
|
||||||
|
PRInt32 aModType)
|
||||||
|
{
|
||||||
|
if (aNameSpaceID != kNameSpaceID_XML || aAttribute != nsGkAtoms::space) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRUint32 count = aDocument->GetNumberOfShells();
|
||||||
|
for (PRUint32 i = 0; i < count; ++i) {
|
||||||
|
nsIFrame *frame = aDocument->GetShellAt(i)->GetPrimaryFrameFor(aContent);
|
||||||
|
if (!frame) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// is the content a child of a text element
|
||||||
|
nsISVGTextContentMetrics* metrics;
|
||||||
|
CallQueryInterface(frame, &metrics);
|
||||||
|
if (metrics) {
|
||||||
|
nsSVGTextFrame* textFrame = NS_STATIC_CAST(nsSVGTextContainerFrame*,
|
||||||
|
frame)->GetTextFrame();
|
||||||
|
|
||||||
|
if (!textFrame->IsGlyphFragmentTreeSuspended())
|
||||||
|
textFrame->UpdateFragmentTree();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// if not, are there text elements amongst its descendents
|
||||||
|
UpdateTextFragmentTrees(frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Implementation helpers
|
||||||
|
|
||||||
|
void
|
||||||
|
nsSVGMutationObserver::UpdateTextFragmentTrees(nsIFrame *aFrame)
|
||||||
|
{
|
||||||
|
nsIFrame* kid = aFrame->GetFirstChild(nsnull);
|
||||||
|
while (kid) {
|
||||||
|
if (kid->GetType() == nsLayoutAtoms::svgTextFrame) {
|
||||||
|
nsSVGTextFrame* textFrame = NS_STATIC_CAST(nsSVGTextFrame*, kid);
|
||||||
|
if (!textFrame->IsGlyphFragmentTreeSuspended()) {
|
||||||
|
textFrame->UpdateFragmentTree();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
UpdateTextFragmentTrees(kid);
|
||||||
|
}
|
||||||
|
kid = kid->GetNextSibling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Implementation
|
// Implementation
|
||||||
|
|
||||||
|
@ -77,6 +163,14 @@ nsSVGOuterSVGFrame::nsSVGOuterSVGFrame(nsStyleContext* aContext)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsSVGOuterSVGFrame::~nsSVGOuterSVGFrame()
|
||||||
|
{
|
||||||
|
nsIDocument *doc = mContent->GetOwnerDoc();
|
||||||
|
if (doc) {
|
||||||
|
doc->RemoveMutationObserver(&sSVGMutationObserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSVGOuterSVGFrame::InitSVG()
|
nsSVGOuterSVGFrame::InitSVG()
|
||||||
{
|
{
|
||||||
|
@ -96,12 +190,15 @@ nsSVGOuterSVGFrame::InitSVG()
|
||||||
NS_ASSERTION(SVGElement, "wrong content element");
|
NS_ASSERTION(SVGElement, "wrong content element");
|
||||||
SVGElement->SetParentCoordCtxProvider(this);
|
SVGElement->SetParentCoordCtxProvider(this);
|
||||||
|
|
||||||
// we only care about our content's zoom and pan values if it's the root element
|
|
||||||
nsIDocument* doc = mContent->GetCurrentDoc();
|
nsIDocument* doc = mContent->GetCurrentDoc();
|
||||||
if (doc && doc->GetRootContent() == mContent) {
|
if (doc) {
|
||||||
SVGElement->GetZoomAndPanEnum(getter_AddRefs(mZoomAndPan));
|
// we only care about our content's zoom and pan values if it's the root element
|
||||||
SVGElement->GetCurrentTranslate(getter_AddRefs(mCurrentTranslate));
|
if (doc->GetRootContent() == mContent) {
|
||||||
SVGElement->GetCurrentScaleNumber(getter_AddRefs(mCurrentScale));
|
SVGElement->GetZoomAndPanEnum(getter_AddRefs(mZoomAndPan));
|
||||||
|
SVGElement->GetCurrentTranslate(getter_AddRefs(mCurrentTranslate));
|
||||||
|
SVGElement->GetCurrentScaleNumber(getter_AddRefs(mCurrentScale));
|
||||||
|
}
|
||||||
|
doc->AddMutationObserver(&sSVGMutationObserver);
|
||||||
}
|
}
|
||||||
|
|
||||||
SuspendRedraw();
|
SuspendRedraw();
|
||||||
|
|
|
@ -61,6 +61,7 @@ class nsSVGOuterSVGFrame : public nsSVGOuterSVGFrameBase,
|
||||||
NS_NewSVGOuterSVGFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
NS_NewSVGOuterSVGFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||||
protected:
|
protected:
|
||||||
nsSVGOuterSVGFrame(nsStyleContext* aContext);
|
nsSVGOuterSVGFrame(nsStyleContext* aContext);
|
||||||
|
virtual ~nsSVGOuterSVGFrame();
|
||||||
NS_IMETHOD InitSVG();
|
NS_IMETHOD InitSVG();
|
||||||
|
|
||||||
// nsISupports interface:
|
// nsISupports interface:
|
||||||
|
|
|
@ -64,7 +64,7 @@ class nsSVGPathGeometryFrame : public nsSVGPathGeometryFrameBase,
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsSVGPathGeometryFrame(nsStyleContext* aContext);
|
nsSVGPathGeometryFrame(nsStyleContext* aContext);
|
||||||
virtual ~nsSVGPathGeometryFrame();
|
~nsSVGPathGeometryFrame();
|
||||||
|
|
||||||
// nsISupports interface:
|
// nsISupports interface:
|
||||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||||
|
@ -127,6 +127,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
void Render(nsISVGRendererCanvas *aCanvas);
|
void Render(nsISVGRendererCanvas *aCanvas);
|
||||||
void GeneratePath(cairo_t *ctx, nsISVGCairoCanvas* aCanvas);
|
void GeneratePath(cairo_t *ctx, nsISVGCairoCanvas* aCanvas);
|
||||||
|
void RemovePathProperties();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for what cairo returns for the fill extents of a degenerate path
|
* Check for what cairo returns for the fill extents of a degenerate path
|
||||||
|
|
|
@ -72,7 +72,7 @@ nsSVGTextContainerFrame::GetX()
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
|
||||||
if (!mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::x))
|
if (!mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::x))
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
|
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
|
||||||
tpElement->GetX(getter_AddRefs(animLengthList));
|
tpElement->GetX(getter_AddRefs(animLengthList));
|
||||||
|
@ -91,7 +91,7 @@ nsSVGTextContainerFrame::GetY()
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
|
||||||
if (!mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::y))
|
if (!mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::y))
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
|
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
|
||||||
tpElement->GetY(getter_AddRefs(animLengthList));
|
tpElement->GetY(getter_AddRefs(animLengthList));
|
||||||
|
@ -311,8 +311,24 @@ nsSVGTextContainerFrame::SetWhitespaceHandling()
|
||||||
nsISVGGlyphFragmentNode* node = GetFirstGlyphFragmentChildNode();
|
nsISVGGlyphFragmentNode* node = GetFirstGlyphFragmentChildNode();
|
||||||
nsISVGGlyphFragmentNode* next;
|
nsISVGGlyphFragmentNode* next;
|
||||||
|
|
||||||
// XXX should inspect xml:space
|
PRUint8 whitespaceHandling = COMPRESS_WHITESPACE | TRIM_LEADING_WHITESPACE;
|
||||||
PRUint8 whitespaceHandling = (COMPRESS_WHITESPACE | TRIM_LEADING_WHITESPACE);
|
|
||||||
|
for (nsIFrame *frame = this; frame != nsnull; frame = frame->GetParent()) {
|
||||||
|
nsIContent *content = frame->GetContent();
|
||||||
|
static nsIContent::AttrValuesArray strings[] =
|
||||||
|
{&nsGkAtoms::preserve, &nsGkAtoms::_default, nsnull};
|
||||||
|
|
||||||
|
PRInt32 index = content->FindAttrValueIn(kNameSpaceID_XML,
|
||||||
|
nsGkAtoms::space,
|
||||||
|
strings, eCaseMatters);
|
||||||
|
if (index == 0) {
|
||||||
|
whitespaceHandling = PRESERVE_WHITESPACE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (index != nsIContent::ATTR_MISSING ||
|
||||||
|
(frame->GetStateBits() & NS_STATE_IS_OUTER_SVG))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
while (node) {
|
while (node) {
|
||||||
next = GetNextGlyphFragmentChildNode(node);
|
next = GetNextGlyphFragmentChildNode(node);
|
||||||
|
|
|
@ -119,10 +119,10 @@ public:
|
||||||
void NotifyGlyphFragmentTreeChange(nsISVGGlyphFragmentNode* caller);
|
void NotifyGlyphFragmentTreeChange(nsISVGGlyphFragmentNode* caller);
|
||||||
PRBool IsMetricsSuspended();
|
PRBool IsMetricsSuspended();
|
||||||
PRBool IsGlyphFragmentTreeSuspended();
|
PRBool IsGlyphFragmentTreeSuspended();
|
||||||
|
void UpdateFragmentTree();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void EnsureFragmentTreeUpToDate();
|
void EnsureFragmentTreeUpToDate();
|
||||||
void UpdateFragmentTree();
|
|
||||||
void UpdateGlyphPositioning();
|
void UpdateGlyphPositioning();
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMSVGMatrix> mCanvasTM;
|
nsCOMPtr<nsIDOMSVGMatrix> mCanvasTM;
|
||||||
|
|
|
@ -59,7 +59,6 @@
|
||||||
#include "nsISVGRenderer.h"
|
#include "nsISVGRenderer.h"
|
||||||
#include "nsSVGFilterFrame.h"
|
#include "nsSVGFilterFrame.h"
|
||||||
#include "nsINameSpaceManager.h"
|
#include "nsINameSpaceManager.h"
|
||||||
#include "nsISVGChildFrame.h"
|
|
||||||
#include "nsIDOMSVGPoint.h"
|
#include "nsIDOMSVGPoint.h"
|
||||||
#include "nsSVGPoint.h"
|
#include "nsSVGPoint.h"
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
|
|
Загрузка…
Ссылка в новой задаче