зеркало из https://github.com/mozilla/gecko-dev.git
Bug 319786 - implement xml:space handling. r=tor,sr=roc
This commit is contained in:
Родитель
2354bf17ad
Коммит
27faef4977
|
@ -86,6 +86,12 @@ nsSVGForeignObjectFrame::nsSVGForeignObjectFrame(nsStyleContext* aContext)
|
|||
{
|
||||
}
|
||||
|
||||
void nsSVGForeignObjectFrame::Destroy()
|
||||
{
|
||||
nsSVGUtils::StyleEffects(this);
|
||||
nsSVGForeignObjectFrameBase::Destroy();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISupports methods
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ class nsSVGForeignObjectFrame : public nsSVGForeignObjectFrameBase,
|
|||
NS_NewSVGForeignObjectFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
protected:
|
||||
nsSVGForeignObjectFrame(nsStyleContext* aContext);
|
||||
virtual void Destroy();
|
||||
|
||||
// nsISupports interface:
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
|
|
|
@ -72,6 +72,12 @@ NS_NewSVGGFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext*
|
|||
return new (aPresShell) nsSVGGFrame(aContext);
|
||||
}
|
||||
|
||||
void nsSVGGFrame::Destroy()
|
||||
{
|
||||
nsSVGUtils::StyleEffects(this);
|
||||
nsSVGGFrameBase::Destroy();
|
||||
}
|
||||
|
||||
nsIAtom *
|
||||
nsSVGGFrame::GetType() const
|
||||
{
|
||||
|
|
|
@ -54,6 +54,7 @@ class nsSVGGFrame : public nsSVGGFrameBase,
|
|||
public:
|
||||
nsSVGGFrame(nsStyleContext* aContext) :
|
||||
nsSVGGFrameBase(aContext), mPropagateTransform(PR_TRUE) {}
|
||||
virtual void Destroy();
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
|
|
|
@ -536,6 +536,15 @@ nsSVGGlyphFrame::GetCharacterData(nsAString & aCharacterData)
|
|||
trimTrailingWhitespace = ((mWhitespaceHandling & TRIM_TRAILING_WHITESPACE) != 0);
|
||||
characterData.CompressWhitespace(trimLeadingWhitespace,
|
||||
trimTrailingWhitespace);
|
||||
} else {
|
||||
nsAString::iterator start, end;
|
||||
characterData.BeginWriting(start);
|
||||
characterData.EndWriting(end);
|
||||
while (start != end) {
|
||||
if (NS_IsAsciiWhitespace(*start))
|
||||
*start = ' ';
|
||||
++start;
|
||||
}
|
||||
}
|
||||
aCharacterData = characterData;
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ class nsSVGInnerSVGFrame : public nsSVGInnerSVGFrameBase,
|
|||
NS_NewSVGInnerSVGFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
protected:
|
||||
nsSVGInnerSVGFrame(nsStyleContext* aContext);
|
||||
virtual void Destroy();
|
||||
|
||||
// nsISupports interface:
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
|
@ -138,6 +139,12 @@ nsSVGInnerSVGFrame::nsSVGInnerSVGFrame(nsStyleContext* aContext) :
|
|||
#endif
|
||||
}
|
||||
|
||||
void nsSVGInnerSVGFrame::Destroy()
|
||||
{
|
||||
nsSVGUtils::StyleEffects(this);
|
||||
nsSVGInnerSVGFrameBase::Destroy();
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGInnerSVGFrame::UpdateCoordCtx()
|
||||
{
|
||||
|
|
|
@ -40,18 +40,104 @@
|
|||
#include "nsIDOMSVGSVGElement.h"
|
||||
#include "nsISVGRenderer.h"
|
||||
#include "nsSVGSVGElement.h"
|
||||
#include "nsSVGTextFrame.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsReflowPath.h"
|
||||
#include "nsSVGRect.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsISVGRendererCanvas.h"
|
||||
#include "nsStubMutationObserver.h"
|
||||
|
||||
#if defined(DEBUG) && defined(SVG_DEBUG_PRINTING)
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsTransform2D.h"
|
||||
#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
|
||||
|
||||
|
@ -77,6 +163,14 @@ nsSVGOuterSVGFrame::nsSVGOuterSVGFrame(nsStyleContext* aContext)
|
|||
{
|
||||
}
|
||||
|
||||
nsSVGOuterSVGFrame::~nsSVGOuterSVGFrame()
|
||||
{
|
||||
nsIDocument *doc = mContent->GetOwnerDoc();
|
||||
if (doc) {
|
||||
doc->RemoveMutationObserver(&sSVGMutationObserver);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGOuterSVGFrame::InitSVG()
|
||||
{
|
||||
|
@ -96,12 +190,15 @@ nsSVGOuterSVGFrame::InitSVG()
|
|||
NS_ASSERTION(SVGElement, "wrong content element");
|
||||
SVGElement->SetParentCoordCtxProvider(this);
|
||||
|
||||
// we only care about our content's zoom and pan values if it's the root element
|
||||
nsIDocument* doc = mContent->GetCurrentDoc();
|
||||
if (doc && doc->GetRootContent() == mContent) {
|
||||
SVGElement->GetZoomAndPanEnum(getter_AddRefs(mZoomAndPan));
|
||||
SVGElement->GetCurrentTranslate(getter_AddRefs(mCurrentTranslate));
|
||||
SVGElement->GetCurrentScaleNumber(getter_AddRefs(mCurrentScale));
|
||||
if (doc) {
|
||||
// we only care about our content's zoom and pan values if it's the root element
|
||||
if (doc->GetRootContent() == mContent) {
|
||||
SVGElement->GetZoomAndPanEnum(getter_AddRefs(mZoomAndPan));
|
||||
SVGElement->GetCurrentTranslate(getter_AddRefs(mCurrentTranslate));
|
||||
SVGElement->GetCurrentScaleNumber(getter_AddRefs(mCurrentScale));
|
||||
}
|
||||
doc->AddMutationObserver(&sSVGMutationObserver);
|
||||
}
|
||||
|
||||
SuspendRedraw();
|
||||
|
|
|
@ -61,6 +61,7 @@ class nsSVGOuterSVGFrame : public nsSVGOuterSVGFrameBase,
|
|||
NS_NewSVGOuterSVGFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
protected:
|
||||
nsSVGOuterSVGFrame(nsStyleContext* aContext);
|
||||
virtual ~nsSVGOuterSVGFrame();
|
||||
NS_IMETHOD InitSVG();
|
||||
|
||||
// nsISupports interface:
|
||||
|
|
|
@ -64,7 +64,7 @@ class nsSVGPathGeometryFrame : public nsSVGPathGeometryFrameBase,
|
|||
{
|
||||
public:
|
||||
nsSVGPathGeometryFrame(nsStyleContext* aContext);
|
||||
virtual ~nsSVGPathGeometryFrame();
|
||||
~nsSVGPathGeometryFrame();
|
||||
|
||||
// nsISupports interface:
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
|
@ -127,6 +127,7 @@ protected:
|
|||
private:
|
||||
void Render(nsISVGRendererCanvas *aCanvas);
|
||||
void GeneratePath(cairo_t *ctx, nsISVGCairoCanvas* aCanvas);
|
||||
void RemovePathProperties();
|
||||
|
||||
/*
|
||||
* Check for what cairo returns for the fill extents of a degenerate path
|
||||
|
|
|
@ -72,7 +72,7 @@ nsSVGTextContainerFrame::GetX()
|
|||
return nsnull;
|
||||
|
||||
if (!mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::x))
|
||||
return nsnull;
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
|
||||
tpElement->GetX(getter_AddRefs(animLengthList));
|
||||
|
@ -91,7 +91,7 @@ nsSVGTextContainerFrame::GetY()
|
|||
return nsnull;
|
||||
|
||||
if (!mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::y))
|
||||
return nsnull;
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
|
||||
tpElement->GetY(getter_AddRefs(animLengthList));
|
||||
|
@ -311,8 +311,24 @@ nsSVGTextContainerFrame::SetWhitespaceHandling()
|
|||
nsISVGGlyphFragmentNode* node = GetFirstGlyphFragmentChildNode();
|
||||
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) {
|
||||
next = GetNextGlyphFragmentChildNode(node);
|
||||
|
|
|
@ -119,10 +119,10 @@ public:
|
|||
void NotifyGlyphFragmentTreeChange(nsISVGGlyphFragmentNode* caller);
|
||||
PRBool IsMetricsSuspended();
|
||||
PRBool IsGlyphFragmentTreeSuspended();
|
||||
void UpdateFragmentTree();
|
||||
|
||||
private:
|
||||
void EnsureFragmentTreeUpToDate();
|
||||
void UpdateFragmentTree();
|
||||
void UpdateGlyphPositioning();
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> mCanvasTM;
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
#include "nsISVGRenderer.h"
|
||||
#include "nsSVGFilterFrame.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsISVGChildFrame.h"
|
||||
#include "nsIDOMSVGPoint.h"
|
||||
#include "nsSVGPoint.h"
|
||||
#include "nsDOMError.h"
|
||||
|
|
Загрузка…
Ссылка в новой задаче