00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "nsBlockFrame.h"
00040 #include "nsIDOMSVGGElement.h"
00041 #include "nsIPresContext.h"
00042 #include "nsISVGChildFrame.h"
00043 #include "nsISVGContainerFrame.h"
00044 #include "nsISVGRendererCanvas.h"
00045 #include "nsWeakReference.h"
00046 #include "nsISVGValue.h"
00047 #include "nsISVGValueObserver.h"
00048 #include "nsIDOMSVGTransformable.h"
00049 #include "nsIDOMSVGAnimTransformList.h"
00050 #include "nsIDOMSVGAnimatedLength.h"
00051 #include "nsIDOMSVGLength.h"
00052 #include "nsIDOMSVGForeignObjectElem.h"
00053 #include "nsIDOMSVGMatrix.h"
00054 #include "nsIDOMSVGSVGElement.h"
00055 #include "nsIDOMSVGPoint.h"
00056 #include "nsSpaceManager.h"
00057 #include "nsISVGRendererRegion.h"
00058 #include "nsISVGRenderer.h"
00059 #include "nsISVGOuterSVGFrame.h"
00060 #include "nsTransform2D.h"
00061
00062 typedef nsBlockFrame nsSVGForeignObjectFrameBase;
00063
00064 class nsSVGForeignObjectFrame : public nsSVGForeignObjectFrameBase,
00065 public nsISVGContainerFrame,
00066 public nsISVGChildFrame,
00067 public nsISVGValueObserver,
00068 public nsSupportsWeakReference
00069 {
00070 friend nsresult
00071 NS_NewSVGForeignObjectFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame** aNewFrame);
00072 protected:
00073 nsSVGForeignObjectFrame();
00074 virtual ~nsSVGForeignObjectFrame();
00075 nsresult Init();
00076
00077
00078 NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
00079 private:
00080 NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
00081 NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
00082 public:
00083
00084 NS_IMETHOD Init(nsIPresContext* aPresContext,
00085 nsIContent* aContent,
00086 nsIFrame* aParent,
00087 nsStyleContext* aContext,
00088 nsIFrame* aPrevInFlow);
00089
00090 NS_IMETHOD Reflow(nsIPresContext* aPresContext,
00091 nsHTMLReflowMetrics& aDesiredSize,
00092 const nsHTMLReflowState& aReflowState,
00093 nsReflowStatus& aStatus);
00094
00095 NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
00096 nsIPresShell& aPresShell,
00097 nsIAtom* aListName,
00098 nsIFrame* aFrameList);
00099
00100 NS_IMETHOD InsertFrames(nsIPresContext* aPresContext,
00101 nsIPresShell& aPresShell,
00102 nsIAtom* aListName,
00103 nsIFrame* aPrevFrame,
00104 nsIFrame* aFrameList);
00105
00106 NS_IMETHOD RemoveFrame(nsIPresContext* aPresContext,
00107 nsIPresShell& aPresShell,
00108 nsIAtom* aListName,
00109 nsIFrame* aOldFrame);
00110
00111 NS_IMETHOD ReplaceFrame(nsIPresContext* aPresContext,
00112 nsIPresShell& aPresShell,
00113 nsIAtom* aListName,
00114 nsIFrame* aOldFrame,
00115 nsIFrame* aNewFrame);
00116
00117
00118 NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable);
00119 NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable);
00120
00121
00122
00123
00124
00125 NS_IMETHOD Paint(nsISVGRendererCanvas* canvas, const nsRect& dirtyRectTwips);
00126 NS_IMETHOD GetFrameForPoint(float x, float y, nsIFrame** hit);
00127 NS_IMETHOD_(already_AddRefed<nsISVGRendererRegion>) GetCoveredRegion();
00128 NS_IMETHOD InitialUpdate();
00129 NS_IMETHOD NotifyCTMChanged();
00130 NS_IMETHOD NotifyRedrawSuspended();
00131 NS_IMETHOD NotifyRedrawUnsuspended();
00132 NS_IMETHOD GetBBox(nsIDOMSVGRect **_retval);
00133
00134
00135 NS_IMETHOD_(nsISVGOuterSVGFrame *) GetOuterSVGFrame();
00136
00137 protected:
00138
00139 void Update();
00140 already_AddRefed<nsISVGRendererRegion> DoReflow();
00141 float GetPxPerTwips();
00142 float GetTwipsPerPx();
00143 void TransformPoint(float& x, float& y);
00144 void TransformVector(float& x, float& y);
00145 void GetCTM(nsIDOMSVGMatrix** ctm);
00146
00147 PRBool mIsDirty;
00148 nsCOMPtr<nsIDOMSVGLength> mX;
00149 nsCOMPtr<nsIDOMSVGLength> mY;
00150 nsCOMPtr<nsIDOMSVGLength> mWidth;
00151 nsCOMPtr<nsIDOMSVGLength> mHeight;
00152 };
00153
00154
00155
00156
00157 nsresult
00158 NS_NewSVGForeignObjectFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame** aNewFrame)
00159 {
00160 *aNewFrame = nsnull;
00161
00162 nsCOMPtr<nsIDOMSVGForeignObjectElement> foreignObject = do_QueryInterface(aContent);
00163 if (!foreignObject) {
00164 #ifdef DEBUG
00165 printf("warning: trying to construct an SVGForeignObjectFrame for a content element that doesn't support the right interfaces\n");
00166 #endif
00167 return NS_ERROR_FAILURE;
00168 }
00169
00170 nsSVGForeignObjectFrame* it = new (aPresShell) nsSVGForeignObjectFrame;
00171 if (nsnull == it)
00172 return NS_ERROR_OUT_OF_MEMORY;
00173
00174 *aNewFrame = it;
00175
00176 return NS_OK;
00177 }
00178
00179 nsSVGForeignObjectFrame::nsSVGForeignObjectFrame()
00180 : mIsDirty(PR_TRUE)
00181 {
00182 }
00183
00184 nsSVGForeignObjectFrame::~nsSVGForeignObjectFrame()
00185 {
00186
00187
00188
00189
00190
00191
00192
00193
00194 nsCOMPtr<nsISVGValue> value;
00195 if (mX && (value = do_QueryInterface(mX)))
00196 value->RemoveObserver(this);
00197 if (mY && (value = do_QueryInterface(mY)))
00198 value->RemoveObserver(this);
00199 if (mWidth && (value = do_QueryInterface(mWidth)))
00200 value->RemoveObserver(this);
00201 if (mHeight && (value = do_QueryInterface(mHeight)))
00202 value->RemoveObserver(this);
00203 }
00204
00205 nsresult nsSVGForeignObjectFrame::Init()
00206 {
00207 nsCOMPtr<nsIDOMSVGForeignObjectElement> foreignObject = do_QueryInterface(mContent);
00208 NS_ASSERTION(foreignObject, "wrong content element");
00209
00210 {
00211 nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00212 foreignObject->GetX(getter_AddRefs(length));
00213 length->GetAnimVal(getter_AddRefs(mX));
00214 NS_ASSERTION(mX, "no x");
00215 if (!mX) return NS_ERROR_FAILURE;
00216 nsCOMPtr<nsISVGValue> value = do_QueryInterface(mX);
00217 if (value)
00218 value->AddObserver(this);
00219 }
00220
00221 {
00222 nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00223 foreignObject->GetY(getter_AddRefs(length));
00224 length->GetAnimVal(getter_AddRefs(mY));
00225 NS_ASSERTION(mY, "no y");
00226 if (!mY) return NS_ERROR_FAILURE;
00227 nsCOMPtr<nsISVGValue> value = do_QueryInterface(mY);
00228 if (value)
00229 value->AddObserver(this);
00230 }
00231
00232 {
00233 nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00234 foreignObject->GetWidth(getter_AddRefs(length));
00235 length->GetAnimVal(getter_AddRefs(mWidth));
00236 NS_ASSERTION(mWidth, "no width");
00237 if (!mWidth) return NS_ERROR_FAILURE;
00238 nsCOMPtr<nsISVGValue> value = do_QueryInterface(mWidth);
00239 if (value)
00240 value->AddObserver(this);
00241 }
00242
00243 {
00244 nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00245 foreignObject->GetHeight(getter_AddRefs(length));
00246 length->GetAnimVal(getter_AddRefs(mHeight));
00247 NS_ASSERTION(mHeight, "no height");
00248 if (!mHeight) return NS_ERROR_FAILURE;
00249 nsCOMPtr<nsISVGValue> value = do_QueryInterface(mHeight);
00250 if (value)
00251 value->AddObserver(this);
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 return NS_OK;
00269 }
00270
00271
00272
00273
00274 NS_INTERFACE_MAP_BEGIN(nsSVGForeignObjectFrame)
00275 NS_INTERFACE_MAP_ENTRY(nsISVGChildFrame)
00276 NS_INTERFACE_MAP_ENTRY(nsISVGContainerFrame)
00277 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
00278 NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
00279 NS_INTERFACE_MAP_END_INHERITING(nsSVGForeignObjectFrameBase)
00280
00281
00282
00283
00284 NS_IMETHODIMP
00285 nsSVGForeignObjectFrame::Init(nsIPresContext* aPresContext,
00286 nsIContent* aContent,
00287 nsIFrame* aParent,
00288 nsStyleContext* aContext,
00289 nsIFrame* aPrevInFlow)
00290 {
00291 nsresult rv;
00292 rv = nsSVGForeignObjectFrameBase::Init(aPresContext, aContent, aParent,
00293 aContext, aPrevInFlow);
00294
00295 Init();
00296
00297 return rv;
00298 }
00299
00300 NS_IMETHODIMP
00301 nsSVGForeignObjectFrame::Reflow(nsIPresContext* aPresContext,
00302 nsHTMLReflowMetrics& aDesiredSize,
00303 const nsHTMLReflowState& aReflowState,
00304 nsReflowStatus& aStatus)
00305 {
00306 #ifdef DEBUG
00307 printf("nsSVGForeignObjectFrame(%p)::Reflow\n", this);
00308 #endif
00309
00310 float twipsPerPx = GetTwipsPerPx();
00311
00312 NS_ENSURE_TRUE(mX && mY && mWidth && mHeight, NS_ERROR_FAILURE);
00313
00314 float x, y, width, height;
00315 mX->GetValue(&x);
00316 mY->GetValue(&y);
00317 mWidth->GetValue(&width);
00318 mHeight->GetValue(&height);
00319
00320
00321
00322
00323
00324 x+=width/2.0f;
00325 y+=height/2.0f;
00326
00327
00328 TransformPoint(x, y);
00329
00330
00331 float e1x = 1.0f, e1y = 0.0f, e2x = 0.0f, e2y = 1.0f;
00332 TransformVector(e1x, e1y);
00333 TransformVector(e2x, e2y);
00334
00335 width *= (float)sqrt(e1x*e1x + e1y*e1y);
00336 height *= (float)sqrt(e2x*e2x + e2y*e2y);
00337
00338
00339 x -= width/2.0f;
00340 y -= height/2.0f;
00341
00342
00343 SetPosition(nsPoint((nscoord) (x*twipsPerPx), (nscoord) (y*twipsPerPx)));
00344
00345
00346
00347 nsSize availableSpace((nscoord)(width*twipsPerPx), (nscoord)(height*twipsPerPx));
00348 nsHTMLReflowState sizedReflowState(aPresContext,
00349 aReflowState,
00350 this,
00351 availableSpace);
00352
00353
00354
00355
00356 mState &= ~NS_FRAME_IS_DIRTY;
00357
00358
00359 return nsSVGForeignObjectFrameBase::Reflow(aPresContext, aDesiredSize,
00360 sizedReflowState, aStatus);
00361 }
00362
00363 NS_IMETHODIMP
00364 nsSVGForeignObjectFrame::AppendFrames(nsIPresContext* aPresContext,
00365 nsIPresShell& aPresShell,
00366 nsIAtom* aListName,
00367 nsIFrame* aFrameList)
00368 {
00369 #ifdef DEBUG
00370 printf("**nsSVGForeignObjectFrame::AppendFrames()\n");
00371 #endif
00372 nsresult rv;
00373 rv = nsSVGForeignObjectFrameBase::AppendFrames(aPresContext, aPresShell,
00374 aListName, aFrameList);
00375 Update();
00376 return rv;
00377 }
00378
00379 NS_IMETHODIMP
00380 nsSVGForeignObjectFrame::InsertFrames(nsIPresContext* aPresContext,
00381 nsIPresShell& aPresShell,
00382 nsIAtom* aListName,
00383 nsIFrame* aPrevFrame,
00384 nsIFrame* aFrameList)
00385 {
00386 #ifdef DEBUG
00387 printf("**nsSVGForeignObjectFrame::InsertFrames()\n");
00388 #endif
00389 nsresult rv;
00390 rv = nsSVGForeignObjectFrameBase::InsertFrames(aPresContext, aPresShell,
00391 aListName, aPrevFrame, aFrameList);
00392 Update();
00393 return rv;
00394 }
00395
00396 NS_IMETHODIMP
00397 nsSVGForeignObjectFrame::RemoveFrame(nsIPresContext* aPresContext,
00398 nsIPresShell& aPresShell,
00399 nsIAtom* aListName,
00400 nsIFrame* aOldFrame)
00401 {
00402 nsresult rv;
00403 rv = nsSVGForeignObjectFrameBase::RemoveFrame(aPresContext, aPresShell,
00404 aListName, aOldFrame);
00405 Update();
00406 return rv;
00407 }
00408
00409 NS_IMETHODIMP
00410 nsSVGForeignObjectFrame::ReplaceFrame(nsIPresContext* aPresContext,
00411 nsIPresShell& aPresShell,
00412 nsIAtom* aListName,
00413 nsIFrame* aOldFrame,
00414 nsIFrame* aNewFrame)
00415 {
00416 #ifdef DEBUG
00417 printf("**nsSVGForeignObjectFrame::ReplaceFrame()\n");
00418 #endif
00419 nsresult rv;
00420 rv = nsSVGForeignObjectFrameBase::ReplaceFrame(aPresContext, aPresShell,
00421 aListName, aOldFrame, aNewFrame);
00422 Update();
00423 return rv;
00424 }
00425
00426
00427
00428
00429 NS_IMETHODIMP
00430 nsSVGForeignObjectFrame::WillModifySVGObservable(nsISVGValue* observable)
00431 {
00432 return NS_OK;
00433 }
00434
00435
00436 NS_IMETHODIMP
00437 nsSVGForeignObjectFrame::DidModifySVGObservable (nsISVGValue* observable)
00438 {
00439 Update();
00440
00441 return NS_OK;
00442 }
00443
00444
00445
00446
00447
00448 NS_IMETHODIMP
00449 nsSVGForeignObjectFrame::Paint(nsISVGRendererCanvas* canvas, const nsRect& dirtyRectTwips)
00450 {
00451 if (mIsDirty) {
00452 nsCOMPtr<nsISVGRendererRegion> region = DoReflow();
00453 }
00454
00455 nsIPresContext *presContext = GetPresContext();
00456
00457 nsRect r(mRect);
00458 if (!r.IntersectRect(dirtyRectTwips, r))
00459 return PR_TRUE;
00460
00461 float pxPerTwips = GetPxPerTwips();
00462 r.x*=pxPerTwips;
00463 r.y*=pxPerTwips;
00464 r.width*=pxPerTwips;
00465 r.height*=pxPerTwips;
00466
00467 nsCOMPtr<nsIRenderingContext> ctx;
00468 canvas->LockRenderingContext(r, getter_AddRefs(ctx));
00469
00470 if (!ctx) {
00471 NS_WARNING("Can't render foreignObject element!");
00472 return NS_ERROR_FAILURE;
00473 }
00474
00475 nsRect dirtyRect = dirtyRectTwips;
00476 dirtyRect.x -= mRect.x;
00477 dirtyRect.y -= mRect.y;
00478
00479
00480
00481 float xMatrix;
00482 float yMatrix;
00483 nsTransform2D *theTransform;
00484 ctx->GetCurrentTransform(theTransform);
00485 theTransform->GetTranslation(&xMatrix, &yMatrix);
00486 ctx->Translate(mRect.x, mRect.y);
00487
00488 nsSVGForeignObjectFrameBase::Paint(presContext,
00489 *ctx,
00490 dirtyRect,
00491 NS_FRAME_PAINT_LAYER_BACKGROUND,
00492 0);
00493
00494 nsSVGForeignObjectFrameBase::Paint(presContext,
00495 *ctx,
00496 dirtyRect,
00497 NS_FRAME_PAINT_LAYER_FLOATERS,
00498 0);
00499
00500 nsSVGForeignObjectFrameBase::Paint(presContext,
00501 *ctx,
00502 dirtyRect,
00503 NS_FRAME_PAINT_LAYER_FOREGROUND,
00504 0);
00505
00506 theTransform->SetTranslation(xMatrix, yMatrix);
00507 ctx = nsnull;
00508 canvas->UnlockRenderingContext();
00509
00510 return NS_OK;
00511 }
00512
00513
00514 NS_IMETHODIMP
00515 nsSVGForeignObjectFrame::GetFrameForPoint(float x, float y, nsIFrame** hit)
00516 {
00517 *hit = nsnull;
00518
00519 nsIPresContext *presContext = GetPresContext();
00520
00521 nsPoint p( (nscoord)(x*GetTwipsPerPx()),
00522 (nscoord)(y*GetTwipsPerPx()));
00523
00524 nsresult rv;
00525
00526 rv = nsSVGForeignObjectFrameBase::GetFrameForPoint(presContext, p,
00527 NS_FRAME_PAINT_LAYER_FOREGROUND, hit);
00528 if (NS_SUCCEEDED(rv) && *hit) return rv;
00529
00530 rv = nsSVGForeignObjectFrameBase::GetFrameForPoint(presContext, p,
00531 NS_FRAME_PAINT_LAYER_FLOATERS, hit);
00532 if (NS_SUCCEEDED(rv) && *hit) return rv;
00533
00534 return nsSVGForeignObjectFrameBase::GetFrameForPoint(presContext, p,
00535 NS_FRAME_PAINT_LAYER_BACKGROUND, hit);
00536 }
00537
00538 NS_IMETHODIMP_(already_AddRefed<nsISVGRendererRegion>)
00539 nsSVGForeignObjectFrame::GetCoveredRegion()
00540 {
00541
00542
00543
00544 nsISVGOuterSVGFrame *outerSVGFrame = GetOuterSVGFrame();
00545 if (!outerSVGFrame) {
00546 NS_ERROR("null outerSVGFrame");
00547 return nsnull;
00548 }
00549
00550 nsCOMPtr<nsISVGRenderer> renderer;
00551 outerSVGFrame->GetRenderer(getter_AddRefs(renderer));
00552
00553 float pxPerTwips = GetPxPerTwips();
00554
00555 nsISVGRendererRegion *region = nsnull;
00556 renderer->CreateRectRegion((mRect.x-1) * pxPerTwips,
00557 (mRect.y-1) * pxPerTwips,
00558 (mRect.width+2) * pxPerTwips,
00559 (mRect.height+2) * pxPerTwips,
00560 ®ion);
00561 NS_ASSERTION(region, "could not create region");
00562 return region;
00563
00564 }
00565
00566 NS_IMETHODIMP
00567 nsSVGForeignObjectFrame::InitialUpdate()
00568 {
00569
00570 return NS_OK;
00571 }
00572
00573 NS_IMETHODIMP
00574 nsSVGForeignObjectFrame::NotifyCTMChanged()
00575 {
00576 Update();
00577 return NS_OK;
00578 }
00579
00580 NS_IMETHODIMP
00581 nsSVGForeignObjectFrame::NotifyRedrawSuspended()
00582 {
00583 return NS_OK;
00584 }
00585
00586 NS_IMETHODIMP
00587 nsSVGForeignObjectFrame::NotifyRedrawUnsuspended()
00588 {
00589 if (mIsDirty) {
00590 nsCOMPtr<nsISVGRendererRegion> dirtyRegion = DoReflow();
00591 if (dirtyRegion) {
00592 nsISVGOuterSVGFrame *outerSVGFrame = GetOuterSVGFrame();
00593 if (outerSVGFrame)
00594 outerSVGFrame->InvalidateRegion(dirtyRegion, PR_TRUE);
00595 }
00596 }
00597 return NS_OK;
00598 }
00599
00600 NS_IMETHODIMP
00601 nsSVGForeignObjectFrame::GetBBox(nsIDOMSVGRect **_retval)
00602 {
00603 *_retval = nsnull;
00604 return NS_ERROR_FAILURE;
00605 }
00606
00607
00608
00609
00610 NS_IMETHODIMP_(nsISVGOuterSVGFrame *)
00611 nsSVGForeignObjectFrame::GetOuterSVGFrame()
00612 {
00613 NS_ASSERTION(mParent, "null parent");
00614
00615 nsISVGContainerFrame *containerFrame;
00616 mParent->QueryInterface(NS_GET_IID(nsISVGContainerFrame), (void**)&containerFrame);
00617 if (!containerFrame) {
00618 NS_ERROR("invalid parent");
00619 return nsnull;
00620 }
00621
00622 return containerFrame->GetOuterSVGFrame();
00623 }
00624
00625
00626
00627
00628 void nsSVGForeignObjectFrame::Update()
00629 {
00630 #ifdef DEBUG
00631 printf("**nsSVGForeignObjectFrame::Update()\n");
00632 #endif
00633
00634 mIsDirty = PR_TRUE;
00635
00636 nsISVGOuterSVGFrame *outerSVGFrame = GetOuterSVGFrame();
00637 if (!outerSVGFrame) {
00638 NS_ERROR("null outerSVGFrame");
00639 return;
00640 }
00641
00642 PRBool suspended;
00643 outerSVGFrame->IsRedrawSuspended(&suspended);
00644 if (!suspended) {
00645 nsCOMPtr<nsISVGRendererRegion> dirtyRegion = DoReflow();
00646 if (dirtyRegion) {
00647 outerSVGFrame->InvalidateRegion(dirtyRegion, PR_TRUE);
00648 }
00649 }
00650 }
00651
00652 already_AddRefed<nsISVGRendererRegion>
00653 nsSVGForeignObjectFrame::DoReflow()
00654 {
00655 #ifdef DEBUG
00656 printf("**nsSVGForeignObjectFrame::DoReflow()\n");
00657 #endif
00658
00659 nsIPresContext *presContext = GetPresContext();
00660
00661
00662 nsCOMPtr<nsISVGRendererRegion> area_before = GetCoveredRegion();
00663 NS_ASSERTION(area_before, "could not get covered region");
00664
00665
00666 nsSize availableSpace(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
00667 nsCOMPtr<nsIRenderingContext> renderingContext;
00668 nsCOMPtr<nsIPresShell> presShell;
00669 presContext->GetShell(getter_AddRefs(presShell));
00670 NS_ASSERTION(presShell, "null presShell");
00671 presShell->CreateRenderingContext(this,getter_AddRefs(renderingContext));
00672
00673
00674 nsHTMLReflowState reflowState(presContext, this, eReflowReason_Initial,
00675 renderingContext, availableSpace);
00676
00677 nsSpaceManager* spaceManager = new nsSpaceManager(presShell, this);
00678 if (!spaceManager) {
00679 NS_ERROR("Could not create space manager");
00680 return nsnull;
00681 }
00682 reflowState.mSpaceManager = spaceManager;
00683
00684 nsHTMLReflowMetrics desiredSize(nsnull);
00685 nsReflowStatus status;
00686
00687 WillReflow(presContext);
00688 Reflow(presContext, desiredSize, reflowState, status);
00689 SetSize(nsSize(desiredSize.width, desiredSize.height));
00690 DidReflow(presContext, &reflowState, NS_FRAME_REFLOW_FINISHED);
00691
00692 mIsDirty = PR_FALSE;
00693
00694 nsCOMPtr<nsISVGRendererRegion> area_after = GetCoveredRegion();
00695 nsISVGRendererRegion *dirtyRegion;
00696 area_before->Combine(area_after, &dirtyRegion);
00697
00698 return dirtyRegion;
00699 }
00700
00701 float nsSVGForeignObjectFrame::GetPxPerTwips()
00702 {
00703 float val = GetTwipsPerPx();
00704
00705 NS_ASSERTION(val!=0.0f, "invalid px/twips");
00706 if (val == 0.0) val = 1e-20f;
00707
00708 return 1.0f/val;
00709 }
00710
00711 float nsSVGForeignObjectFrame::GetTwipsPerPx()
00712 {
00713 float twipsPerPx=16.0f;
00714
00715 GetPresContext()->GetScaledPixelsToTwips(&twipsPerPx);
00716 return twipsPerPx;
00717 }
00718
00719 void nsSVGForeignObjectFrame::TransformPoint(float& x, float& y)
00720 {
00721 nsCOMPtr<nsIDOMSVGMatrix> ctm;
00722 GetCTM(getter_AddRefs(ctm));
00723 if (!ctm) return;
00724
00725
00726
00727
00728
00729 nsCOMPtr<nsIDOMSVGElement> el = do_QueryInterface(mContent);
00730 nsCOMPtr<nsIDOMSVGSVGElement> svg_el;
00731 el->GetOwnerSVGElement(getter_AddRefs(svg_el));
00732 if (!svg_el) return;
00733 nsCOMPtr<nsIDOMSVGPoint> point;
00734 svg_el->CreateSVGPoint(getter_AddRefs(point));
00735 NS_ASSERTION(point, "couldn't create point!");
00736 if (!point) return;
00737
00738 point->SetX(x);
00739 point->SetY(y);
00740 nsCOMPtr<nsIDOMSVGPoint> xfpoint;
00741 point->MatrixTransform(ctm, getter_AddRefs(xfpoint));
00742 xfpoint->GetX(&x);
00743 xfpoint->GetY(&y);
00744 }
00745
00746 void nsSVGForeignObjectFrame::TransformVector(float& x, float& y)
00747 {
00748
00749
00750
00751 float x0=0.0f, y0=0.0f;
00752 TransformPoint(x0, y0);
00753 TransformPoint(x,y);
00754 x -= x0;
00755 y -= y0;
00756 }
00757
00758 void nsSVGForeignObjectFrame::GetCTM(nsIDOMSVGMatrix** ctm)
00759 {
00760 *ctm = nsnull;
00761
00762 nsCOMPtr<nsIDOMSVGTransformable> transformable = do_QueryInterface(mContent);
00763 NS_ASSERTION(transformable, "wrong content type");
00764
00765 transformable->GetCTM(ctm);
00766 }
00767
00768