diff --git a/mozilla/content/base/src/nsGenericElement.cpp b/mozilla/content/base/src/nsGenericElement.cpp index 25b1f2a4935..ccd4a9cbec2 100644 --- a/mozilla/content/base/src/nsGenericElement.cpp +++ b/mozilla/content/base/src/nsGenericElement.cpp @@ -739,7 +739,7 @@ TryGetSVGBoundingRect(nsIFrame* aFrame, nsRect* aRect) // r is in pixels relative to 'outer', get it into twips // relative to ICB origin - r.ScaleRoundOut(1.0/aFrame->PresContext()->AppUnitsPerCSSPixel()); + r.ScaleRoundOut(1.0/aFrame->PresContext()->AppUnitsPerDevPixel()); *aRect = r + GetOffsetFromInitialContainingBlock(outer); return PR_TRUE; #else diff --git a/mozilla/layout/svg/base/src/nsISVGChildFrame.h b/mozilla/layout/svg/base/src/nsISVGChildFrame.h index 0e01c82f6e2..14c263e59a5 100644 --- a/mozilla/layout/svg/base/src/nsISVGChildFrame.h +++ b/mozilla/layout/svg/base/src/nsISVGChildFrame.h @@ -74,6 +74,7 @@ public: // See bug 290852 for foreignObject complications. NS_IMETHOD GetFrameForPointSVG(float x, float y, nsIFrame** hit)=0; + // Get bounds in our gfxContext's coordinates space (in device pixels) NS_IMETHOD_(nsRect) GetCoveredRegion()=0; NS_IMETHOD UpdateCoveredRegion()=0; diff --git a/mozilla/layout/svg/base/src/nsSVGClipPathFrame.cpp b/mozilla/layout/svg/base/src/nsSVGClipPathFrame.cpp index 08f16b593cc..261f73289a1 100644 --- a/mozilla/layout/svg/base/src/nsSVGClipPathFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGClipPathFrame.cpp @@ -194,30 +194,7 @@ nsSVGClipPathFrame::GetCanvasTM() else canvasTM = mClipParentMatrix; - /* object bounding box? */ - PRUint16 units = - clipPath->mEnumAttributes[nsSVGClipPathElement::CLIPPATHUNITS].GetAnimValue(); - - if (mClipParent && - units == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { - nsCOMPtr rect; - nsresult rv = mClipParent->GetBBox(getter_AddRefs(rect)); - - if (NS_SUCCEEDED(rv)) { - float minx, miny, width, height; - rect->GetX(&minx); - rect->GetY(&miny); - rect->GetWidth(&width); - rect->GetHeight(&height); - - nsCOMPtr tmp, fini; - canvasTM->Translate(minx, miny, getter_AddRefs(tmp)); - tmp->ScaleNonUniform(width, height, getter_AddRefs(fini)); - canvasTM = fini; - } - } - - nsIDOMSVGMatrix* retval = canvasTM.get(); - NS_IF_ADDREF(retval); - return retval; + return nsSVGUtils::AdjustMatrixForUnits(canvasTM, + &clipPath->mEnumAttributes[nsSVGClipPathElement::CLIPPATHUNITS], + mClipParent); } diff --git a/mozilla/layout/svg/base/src/nsSVGContainerFrame.h b/mozilla/layout/svg/base/src/nsSVGContainerFrame.h index 9813435b199..61397297850 100644 --- a/mozilla/layout/svg/base/src/nsSVGContainerFrame.h +++ b/mozilla/layout/svg/base/src/nsSVGContainerFrame.h @@ -54,6 +54,7 @@ protected: nsSVGContainerFrameBase(aContext) {} public: + // Returns the transform to our gfxContext (to device pixels, not CSS px) virtual already_AddRefed GetCanvasTM() { return nsnull; } // nsIFrame: diff --git a/mozilla/layout/svg/base/src/nsSVGFilterFrame.h b/mozilla/layout/svg/base/src/nsSVGFilterFrame.h index 2dd8cb460b3..ced92acb7eb 100644 --- a/mozilla/layout/svg/base/src/nsSVGFilterFrame.h +++ b/mozilla/layout/svg/base/src/nsSVGFilterFrame.h @@ -52,6 +52,10 @@ protected: public: nsresult FilterPaint(nsSVGRenderState *aContext, nsISVGChildFrame *aTarget); + + // Returns invalidation region for filter (can be bigger than the + // referencing geometry to filter region sizing) in device pixels + // relative to the origin of the outer svg. nsRect GetInvalidationRegion(nsIFrame *aTarget); /** diff --git a/mozilla/layout/svg/base/src/nsSVGForeignObjectFrame.cpp b/mozilla/layout/svg/base/src/nsSVGForeignObjectFrame.cpp index ab35c24ae22..cf91068dfec 100644 --- a/mozilla/layout/svg/base/src/nsSVGForeignObjectFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGForeignObjectFrame.cpp @@ -291,10 +291,11 @@ nsSVGForeignObjectFrame::TransformPointFromOuterPx(float aX, float aY, nsPoint* nsresult rv = tm->Inverse(getter_AddRefs(inverse)); if (NS_FAILED(rv)) return rv; - + nsSVGUtils::TransformPoint(inverse, &aX, &aY); - *aOut = nsPoint(nsPresContext::CSSPixelsToAppUnits(aX), - nsPresContext::CSSPixelsToAppUnits(aY)); + PRInt32 appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); + *aOut = nsPoint(NSToCoordRound(aX * appUnitsPerDevPixel), + NSToCoordRound(aY * appUnitsPerDevPixel)); return NS_OK; } @@ -322,8 +323,9 @@ nsPoint nsSVGForeignObjectFrame::TransformPointFromOuter(nsPoint aPt) { nsPoint pt(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); - TransformPointFromOuterPx(nsPresContext::AppUnitsToFloatCSSPixels(aPt.x), - nsPresContext::AppUnitsToFloatCSSPixels(aPt.y), + float appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); + TransformPointFromOuterPx(aPt.x / appUnitsPerDevPixel, + aPt.y / appUnitsPerDevPixel, &pt); return pt; } @@ -697,7 +699,7 @@ nsSVGForeignObjectFrame::FlushDirtyRegion() nsCOMPtr tm = GetTMIncludingOffset(); nsRect r = mDirtyRegion.GetBounds(); - r.ScaleRoundOut(1.0f / nsPresContext::AppUnitsPerCSSPixel()); + r.ScaleRoundOut(1.0f / PresContext()->AppUnitsPerDevPixel()); float x = r.x, y = r.y, w = r.width, h = r.height; r = GetTransformedRegion(x, y, w, h, tm); outerSVGFrame->InvalidateRect(r); diff --git a/mozilla/layout/svg/base/src/nsSVGGlyphFrame.cpp b/mozilla/layout/svg/base/src/nsSVGGlyphFrame.cpp index 77c3cc81396..22151fa19a5 100644 --- a/mozilla/layout/svg/base/src/nsSVGGlyphFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGGlyphFrame.cpp @@ -122,7 +122,8 @@ nsSVGGlyphFrame::DidSetStyleContext() // (Ctrl++,Ctrl+-) nsPresContext *presContext = PresContext(); float textZoom = presContext->TextZoom(); - double size = presContext->AppUnitsToDevPixels(fontData->mSize) / textZoom; + double size = + presContext->AppUnitsToFloatCSSPixels(fontData->mSize) / textZoom; nsCAutoString langGroup; nsIAtom *langGroupAtom = presContext->GetLangGroup(); diff --git a/mozilla/layout/svg/base/src/nsSVGMaskFrame.cpp b/mozilla/layout/svg/base/src/nsSVGMaskFrame.cpp index b1012a17e36..1b46bffe352 100644 --- a/mozilla/layout/svg/base/src/nsSVGMaskFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGMaskFrame.cpp @@ -242,35 +242,10 @@ nsSVGMaskFrame::GetCanvasTM() { NS_ASSERTION(mMaskParentMatrix, "null parent matrix"); - nsCOMPtr canvasTM = mMaskParentMatrix; - - /* object bounding box? */ nsSVGMaskElement *mask = static_cast(mContent); - PRUint16 contentUnits = - mask->mEnumAttributes[nsSVGMaskElement::MASKCONTENTUNITS].GetAnimValue(); - - if (mMaskParent && - contentUnits == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { - nsCOMPtr rect; - nsresult rv = mMaskParent->GetBBox(getter_AddRefs(rect)); - - if (NS_SUCCEEDED(rv)) { - float minx, miny, width, height; - rect->GetX(&minx); - rect->GetY(&miny); - rect->GetWidth(&width); - rect->GetHeight(&height); - - nsCOMPtr tmp, fini; - canvasTM->Translate(minx, miny, getter_AddRefs(tmp)); - tmp->ScaleNonUniform(width, height, getter_AddRefs(fini)); - canvasTM = fini; - } - } - - nsIDOMSVGMatrix* retval = canvasTM.get(); - NS_IF_ADDREF(retval); - return retval; + return nsSVGUtils::AdjustMatrixForUnits(mMaskParentMatrix, + &mask->mEnumAttributes[nsSVGMaskElement::MASKCONTENTUNITS], + mMaskParent); } diff --git a/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.cpp b/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.cpp index aea49b82e3b..03c11bc1d28 100644 --- a/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.cpp @@ -157,6 +157,7 @@ NS_NewSVGOuterSVGFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleCo nsSVGOuterSVGFrame::nsSVGOuterSVGFrame(nsStyleContext* aContext) : nsSVGOuterSVGFrameBase(aContext), mRedrawSuspendCount(0), + mFullZoom(0), mViewportInitialized(PR_FALSE) { } @@ -351,8 +352,10 @@ nsSVGOuterSVGFrame::Reflow(nsPresContext* aPresContext, nsSVGSVGElement *svgElem = static_cast(mContent); - if (newViewportSize != svgElem->GetViewportSize()) { + if (newViewportSize != svgElem->GetViewportSize() || + mFullZoom != PresContext()->GetFullZoom()) { svgElem->SetViewportSize(newViewportSize); + mFullZoom = PresContext()->GetFullZoom(); NotifyViewportChange(); } @@ -710,8 +713,15 @@ already_AddRefed nsSVGOuterSVGFrame::GetCanvasTM() { if (!mCanvasTM) { + nsCOMPtr vb2vp; nsSVGSVGElement *svgElement = static_cast(mContent); - svgElement->GetViewboxToViewportTransform(getter_AddRefs(mCanvasTM)); + svgElement->GetViewboxToViewportTransform(getter_AddRefs(vb2vp)); + + // Scale the transform from CSS pixel space to device pixel space + float devPxPerCSSPx = + 1 / PresContext()->AppUnitsToFloatCSSPixels( + PresContext()->AppUnitsPerDevPixel()); + vb2vp->Scale(devPxPerCSSPx, getter_AddRefs(mCanvasTM)); // our content is the document element so we must premultiply the values // of its currentScale and currentTranslate properties diff --git a/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.h b/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.h index a50ab170e92..4da7caac481 100644 --- a/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.h +++ b/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.h @@ -168,6 +168,8 @@ protected: nsCOMPtr mCurrentTranslate; nsCOMPtr mCurrentScale; + float mFullZoom; + PRPackedBool mViewportInitialized; }; diff --git a/mozilla/layout/svg/base/src/nsSVGUtils.cpp b/mozilla/layout/svg/base/src/nsSVGUtils.cpp index 87cd4aadd62..af233d6c194 100644 --- a/mozilla/layout/svg/base/src/nsSVGUtils.cpp +++ b/mozilla/layout/svg/base/src/nsSVGUtils.cpp @@ -81,6 +81,7 @@ #include "gfxPlatform.h" #include "nsSVGForeignObjectFrame.h" #include "nsIFontMetrics.h" +#include "nsIDOMSVGUnitTypes.h" static void AddEffectProperties(nsIFrame *aFrame); @@ -1477,6 +1478,47 @@ nsSVGUtils::MaxExpansion(nsIDOMSVGMatrix *aMatrix) return sqrt(f + sqrt(g * g + h * h)); } +already_AddRefed +nsSVGUtils::AdjustMatrixForUnits(nsIDOMSVGMatrix *aMatrix, + nsSVGEnum *aUnits, + nsISVGChildFrame *aFrame) +{ + nsCOMPtr fini = aMatrix; + + if (aFrame && + aUnits->GetAnimValue() == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { + nsCOMPtr rect; + nsresult rv = aFrame->GetBBox(getter_AddRefs(rect)); + + if (NS_SUCCEEDED(rv)) { + float minx, miny, width, height; + rect->GetX(&minx); + rect->GetY(&miny); + rect->GetWidth(&width); + rect->GetHeight(&height); + + // Correct for scaling in outersvg CTM + nsIFrame *frame; + CallQueryInterface(aFrame, &frame); + nsPresContext *presCtx = frame->PresContext(); + float cssPxPerDevPx = + presCtx->AppUnitsToFloatCSSPixels(presCtx->AppUnitsPerDevPixel()); + minx *= cssPxPerDevPx; + miny *= cssPxPerDevPx; + width *= cssPxPerDevPx; + height *= cssPxPerDevPx; + + nsCOMPtr tmp; + aMatrix->Translate(minx, miny, getter_AddRefs(tmp)); + tmp->ScaleNonUniform(width, height, getter_AddRefs(fini)); + } + } + + nsIDOMSVGMatrix* retval = fini.get(); + NS_IF_ADDREF(retval); + return retval; +} + #ifdef DEBUG void nsSVGUtils::WritePPM(const char *fname, gfxImageSurface *aSurface) diff --git a/mozilla/layout/svg/base/src/nsSVGUtils.h b/mozilla/layout/svg/base/src/nsSVGUtils.h index 85a7cc1ee8e..37ed923f950 100644 --- a/mozilla/layout/svg/base/src/nsSVGUtils.h +++ b/mozilla/layout/svg/base/src/nsSVGUtils.h @@ -75,6 +75,8 @@ struct gfxMatrix; struct gfxSize; struct gfxIntSize; struct nsStyleFont; +class nsSVGEnum; +class nsISVGChildFrame; #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -300,8 +302,9 @@ public: StyleEffects(nsIFrame *aFrame); /* Hit testing - check if point hits the clipPath of indicated - * frame. Returns true of no clipPath set. */ - + * frame. (x,y) are specified in device pixels relative to the + * origin of the outer svg frame. Returns true if no clipPath + * set. */ static PRBool HitTestClip(nsIFrame *aFrame, float x, float y); @@ -391,6 +394,12 @@ public: static float MaxExpansion(nsIDOMSVGMatrix *aMatrix); + /* Take a CTM and adjust for object bounding box coordinates, if needed */ + static already_AddRefed + AdjustMatrixForUnits(nsIDOMSVGMatrix *aMatrix, + nsSVGEnum *aUnits, + nsISVGChildFrame *aFrame); + #ifdef DEBUG static void WritePPM(const char *fname, gfxImageSurface *aSurface);