From f99b6af29bd242fbbb8d2799f8016521dc788895 Mon Sep 17 00:00:00 2001 From: "tor%cs.brown.edu" Date: Sun, 26 Feb 2006 17:58:58 +0000 Subject: [PATCH] Bug 328348 - Single version of viewport transform code. r=jwatt, sr=roc. --- .../svg/content/src/nsSVGMarkerElement.cpp | 64 ++---------- content/svg/content/src/nsSVGSVGElement.cpp | 93 ++---------------- layout/svg/base/src/nsSVGImageFrame.cpp | 84 ++-------------- layout/svg/base/src/nsSVGPatternFrame.cpp | 71 +++----------- layout/svg/base/src/nsSVGUtils.cpp | 97 +++++++++++++++++++ layout/svg/base/src/nsSVGUtils.h | 11 +++ 6 files changed, 144 insertions(+), 276 deletions(-) diff --git a/content/svg/content/src/nsSVGMarkerElement.cpp b/content/svg/content/src/nsSVGMarkerElement.cpp index 427a8468c33d..9710c56d131d 100644 --- a/content/svg/content/src/nsSVGMarkerElement.cpp +++ b/content/svg/content/src/nsSVGMarkerElement.cpp @@ -53,6 +53,7 @@ #include "nsSVGPreserveAspectRatio.h" #include "nsSVGMatrix.h" #include "nsDOMError.h" +#include "nsSVGUtils.h" typedef nsSVGGraphicElement nsSVGMarkerElementBase; @@ -442,48 +443,6 @@ nsSVGMarkerElement::GetViewboxToViewportTransform(nsIDOMSVGMatrix **_retval) viewboxWidth = 1.0f; viewboxHeight = 1.0f; } - - PRUint16 align, meetOrSlice; - { - nsCOMPtr par; - mPreserveAspectRatio->GetAnimVal(getter_AddRefs(par)); - NS_ASSERTION(par, "could not get preserveAspectRatio"); - par->GetAlign(&align); - par->GetMeetOrSlice(&meetOrSlice); - } - - // default to the defaults - if (align == nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_UNKNOWN) - align = nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID; - if (meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_UNKNOWN) - meetOrSlice = nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET; - - float a, d, e, f; - a = viewportWidth/viewboxWidth; - d = viewportHeight/viewboxHeight; - e = 0.0f; - f = 0.0f; - - if (align != nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE && - a != d) { - if (meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET && - a < d || - meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE && - d < a) { - d = a; - } - else if ( - meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET && - d < a || - meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE && - a < d) { - a = d; - } - else NS_NOTREACHED("Unknown value for meetOrSlice"); - } - - if (viewboxX) e += -a * viewboxX; - if (viewboxY) f += -d * viewboxY; float refX; { @@ -491,7 +450,6 @@ nsSVGMarkerElement::GetViewboxToViewportTransform(nsIDOMSVGMatrix **_retval) mRefX->GetAnimVal(getter_AddRefs(l)); l->GetValue(&refX); } - float refY; { nsCOMPtr l; @@ -499,20 +457,12 @@ nsSVGMarkerElement::GetViewboxToViewportTransform(nsIDOMSVGMatrix **_retval) l->GetValue(&refY); } - e -= refX * a; - f -= refY * d; - -#ifdef DEBUG - printf("Marker Viewport=(0?,0?,%f,%f)\n", viewportWidth, viewportHeight); - printf("Marker Viewbox=(%f,%f,%f,%f)\n", viewboxX, viewboxY, viewboxWidth, viewboxHeight); - printf("Marker Viewbox->Viewport xform [a c e] = [%f, 0, %f]\n", a, e); - printf(" [b d f] = [ 0, %f, %f]\n", d, f); -#endif - - rv = NS_NewSVGMatrix(getter_AddRefs(mViewBoxToViewportTransform), - a, 0.0f, - 0.0f, d, - e, f); + mViewBoxToViewportTransform = + nsSVGUtils::GetViewBoxTransform(viewportWidth, viewportHeight, + viewboxX + refX, viewboxY + refY, + viewboxWidth, viewboxHeight, + mPreserveAspectRatio, + PR_TRUE); } *_retval = mViewBoxToViewportTransform; diff --git a/content/svg/content/src/nsSVGSVGElement.cpp b/content/svg/content/src/nsSVGSVGElement.cpp index fe7256bf8793..9ce514fa7eb8 100644 --- a/content/svg/content/src/nsSVGSVGElement.cpp +++ b/content/svg/content/src/nsSVGSVGElement.cpp @@ -71,6 +71,7 @@ #include "nsSVGEnum.h" #include "nsISVGChildFrame.h" #include "nsGUIEvent.h" +#include "nsSVGUtils.h" typedef nsSVGStylableElement nsSVGSVGElementBase; @@ -836,93 +837,11 @@ nsSVGSVGElement::GetViewboxToViewportTransform(nsIDOMSVGMatrix **_retval) viewboxHeight = 1.0f; } - PRUint16 align, meetOrSlice; - { - nsCOMPtr par; - mPreserveAspectRatio->GetAnimVal(getter_AddRefs(par)); - NS_ASSERTION(par, "could not get preserveAspectRatio"); - par->GetAlign(&align); - par->GetMeetOrSlice(&meetOrSlice); - } - - // default to the defaults - if (align == nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_UNKNOWN) - align = nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID; - if (meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_UNKNOWN) - meetOrSlice = nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET; - - float a, d, e, f; - a = viewportWidth/viewboxWidth; - d = viewportHeight/viewboxHeight; - e = 0.0f; - f = 0.0f; - - if (align != nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE && - a != d) { - if (meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET && - a < d || - meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE && - d < a) { - d = a; - switch (align) { - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMIN: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN: - break; - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: - f = (viewportHeight - a * viewboxHeight) / 2.0f; - break; - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: - f = viewportHeight - a * viewboxHeight; - break; - default: - NS_NOTREACHED("Unknown value for align"); - } - } - else if ( - meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET && - d < a || - meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE && - a < d) { - a = d; - switch (align) { - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMIN: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX: - break; - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: - e = (viewportWidth - a * viewboxWidth) / 2.0f; - break; - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: - e = viewportWidth - a * viewboxWidth; - break; - default: - NS_NOTREACHED("Unknown value for align"); - } - } - else NS_NOTREACHED("Unknown value for meetOrSlice"); - } - - if (viewboxX) e += -a * viewboxX; - if (viewboxY) f += -d * viewboxY; - -#ifdef DEBUG - printf("SVG Viewport=(0?,0?,%f,%f)\n", viewportWidth, viewportHeight); - printf("SVG Viewbox=(%f,%f,%f,%f)\n", viewboxX, viewboxY, viewboxWidth, viewboxHeight); - printf("SVG Viewbox->Viewport xform [a c e] = [%f, 0, %f]\n", a, e); - printf(" [b d f] = [ 0, %f, %f]\n", d, f); -#endif - - rv = NS_NewSVGMatrix(getter_AddRefs(mViewBoxToViewportTransform), - a, 0.0f, 0.0f, d, e, f); + mViewBoxToViewportTransform = + nsSVGUtils::GetViewBoxTransform(viewportWidth, viewportHeight, + viewboxX, viewboxY, + viewboxWidth, viewboxHeight, + mPreserveAspectRatio); } *_retval = mViewBoxToViewportTransform; diff --git a/layout/svg/base/src/nsSVGImageFrame.cpp b/layout/svg/base/src/nsSVGImageFrame.cpp index 1bdd8ca332e4..9ecd8212057c 100644 --- a/layout/svg/base/src/nsSVGImageFrame.cpp +++ b/layout/svg/base/src/nsSVGImageFrame.cpp @@ -436,81 +436,17 @@ nsSVGImageFrame::PaintSVG(nsISVGRendererCanvas* canvas, mSurface->GetWidth(&nativeWidth); mSurface->GetHeight(&nativeHeight); - PRUint16 align, meetOrSlice; - mPreserveAspectRatio->GetAlign(&align); - mPreserveAspectRatio->GetMeetOrSlice(&meetOrSlice); + nsCOMPtr element = do_QueryInterface(mContent); + nsCOMPtr ratio; + element->GetPreserveAspectRatio(getter_AddRefs(ratio)); - // default to the defaults - if (align == nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_UNKNOWN) - align = nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID; - if (meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_UNKNOWN) - meetOrSlice = nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET; - - float a, d, e, f; - a = width/nativeWidth; - d = height/nativeHeight; - e = 0.0f; - f = 0.0f; - - if (align != nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE && - a != d) { - if (meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET && - a < d || - meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE && - d < a) { - d = a; - switch (align) { - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMIN: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN: - break; - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: - f = (height - a * nativeHeight) / 2.0f; - break; - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: - f = height - a * nativeHeight; - break; - default: - NS_NOTREACHED("Unknown value for align"); - } - } - else if ( - meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET && - d < a || - meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE && - a < d) { - a = d; - switch (align) { - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMIN: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX: - break; - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: - e = (width - a * nativeWidth) / 2.0f; - break; - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: - case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: - e = width - a * nativeWidth; - break; - default: - NS_NOTREACHED("Unknown value for align"); - } - } - else NS_NOTREACHED("Unknown value for meetOrSlice"); - } - - nsCOMPtr trans; - ctm->Translate(x + e, y + f, getter_AddRefs(trans)); - - nsCOMPtr fini; - trans->ScaleNonUniform(a, d, getter_AddRefs(fini)); + nsCOMPtr trans, ctmXY, fini; + trans = nsSVGUtils::GetViewBoxTransform(width, height, + 0, 0, + nativeWidth, nativeHeight, + ratio); + ctm->Translate(x, y, getter_AddRefs(ctmXY)); + ctmXY->Multiply(trans, getter_AddRefs(fini)); canvas->CompositeSurfaceMatrix(mSurface, fini, diff --git a/layout/svg/base/src/nsSVGPatternFrame.cpp b/layout/svg/base/src/nsSVGPatternFrame.cpp index 54f52b3e9de7..d8584e8a650c 100644 --- a/layout/svg/base/src/nsSVGPatternFrame.cpp +++ b/layout/svg/base/src/nsSVGPatternFrame.cpp @@ -162,7 +162,7 @@ protected: NS_IMETHOD PrivateGetHeight(nsIDOMSVGLength * *aValue); NS_IMETHOD PrivateGetViewBox(nsIDOMSVGAnimatedRect * *aMatrix); NS_IMETHOD PrivateGetPreserveAspectRatio(nsIDOMSVGAnimatedPreserveAspectRatio **aPreserveAspectRatio); - NS_IMETHOD GetPreserveAspectRatio(nsIDOMSVGPreserveAspectRatio **aPreserveAspectRatio); + NS_IMETHOD GetPreserveAspectRatio(nsIDOMSVGAnimatedPreserveAspectRatio **aPreserveAspectRatio); NS_IMETHOD GetPatternFirstChild(nsIFrame **kid); NS_IMETHOD GetViewBox(nsIDOMSVGRect * *aMatrix); nsresult GetPatternRect(nsIDOMSVGRect **patternRect, @@ -625,8 +625,8 @@ nsSVGPatternFrame::GetViewBox(nsIDOMSVGRect **aViewBox) } NS_IMETHODIMP -nsSVGPatternFrame::GetPreserveAspectRatio(nsIDOMSVGPreserveAspectRatio - **aPreserveAspectRatio) +nsSVGPatternFrame::GetPreserveAspectRatio(nsIDOMSVGAnimatedPreserveAspectRatio + **aPreserveAspectRatio) { if (!mPreserveAspectRatio) { PrivateGetPreserveAspectRatio(getter_AddRefs(mPreserveAspectRatio)); @@ -634,7 +634,9 @@ nsSVGPatternFrame::GetPreserveAspectRatio(nsIDOMSVGPreserveAspectRatio return NS_ERROR_FAILURE; NS_ADD_SVGVALUE_OBSERVER(mPreserveAspectRatio); } - mPreserveAspectRatio->GetAnimVal(aPreserveAspectRatio); + *aPreserveAspectRatio = mPreserveAspectRatio; + NS_IF_ADDREF(*aPreserveAspectRatio); + return NS_OK; } @@ -987,71 +989,24 @@ nsSVGPatternFrame::ConstructCTM(nsIDOMSVGMatrix **resultCTM, nsIDOMSVGMatrix *aP aViewRect->GetHeight(&viewBoxHeight); aViewRect->GetWidth(&viewBoxWidth); if (viewBoxHeight != 0.0f && viewBoxWidth != 0.0f) { - // Use the viewbox to calculate the new matrix - PRUint16 align, meetOrSlice; - { - nsCOMPtr par; - GetPreserveAspectRatio(getter_AddRefs(par)); - NS_ASSERTION(par, "could not get preserveAspectRatio"); - par->GetAlign(&align); - par->GetMeetOrSlice(&meetOrSlice); - } - - // default to the defaults - if (align == nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_UNKNOWN) - align = nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID; - if (meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_UNKNOWN) - meetOrSlice = nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET; float viewportWidth, viewportHeight; GetWidth(&viewportWidth); GetHeight(&viewportHeight); - float a, d, e, f; - a = viewportWidth/viewBoxWidth; - d = viewportHeight/viewBoxHeight; - e = 0.0f; - f = 0.0f; - - if (align != nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE && - a != d) { - if (meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET && - a < d || - meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE && - d < a) { - d = a; - } - else if ( - meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET && - d < a || - meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE && - a < d) { - a = d; - } - else NS_NOTREACHED("Unknown value for meetOrSlice"); - } - - if (viewBoxX) e += -a * viewBoxX; - if (viewBoxY) f += -d * viewBoxY; - float refX, refY; GetX(&refX); GetY(&refY); - e -= refX * a; - f -= refY * d; + nsCOMPtr par; + GetPreserveAspectRatio(getter_AddRefs(par)); -#ifdef DEBUG - printf("Pattern Viewport=(0?,0?,%f,%f)\n", viewportWidth, viewportHeight); - printf("Pattern Viewbox=(%f,%f,%f,%f)\n", viewBoxX, viewBoxY, viewBoxWidth, viewBoxHeight); - printf("Pattern Viewbox->Viewport xform [a c e] = [%f, 0, %f]\n", a, e); - printf(" [b d f] = [ 0, %f, %f]\n", d, f); -#endif + tempTM = nsSVGUtils::GetViewBoxTransform(viewportWidth, viewportHeight, + viewBoxX + refX, viewBoxY + refY, + viewBoxWidth, viewBoxHeight, + par, + PR_TRUE); - NS_NewSVGMatrix(getter_AddRefs(tempTM), - a, 0.0f, - 0.0f, d, - e, f); tempTM->Multiply(tCTM, resultCTM); } else { // No viewBox, construct from the (modified) parent matrix diff --git a/layout/svg/base/src/nsSVGUtils.cpp b/layout/svg/base/src/nsSVGUtils.cpp index 7a4870658cbe..8c83483de09d 100644 --- a/layout/svg/base/src/nsSVGUtils.cpp +++ b/layout/svg/base/src/nsSVGUtils.cpp @@ -67,6 +67,9 @@ #include "nsDOMError.h" #include "nsISVGOuterSVGFrame.h" #include "nsISVGRendererCanvas.h" +#include "nsIDOMSVGAnimPresAspRatio.h" +#include "nsIDOMSVGPresAspectRatio.h" +#include "nsSVGMatrix.h" #if defined(MOZ_SVG_RENDERER_GDIPLUS) #include @@ -648,3 +651,97 @@ nsSVGUtils::GetOuterSVGFrame(nsIFrame *aFrame) return outerSVG; } + +already_AddRefed +nsSVGUtils::GetViewBoxTransform(float aViewportWidth, float aViewportHeight, + float aViewboxX, float aViewboxY, + float aViewboxWidth, float aViewboxHeight, + nsIDOMSVGAnimatedPreserveAspectRatio *aPreserveAspectRatio, + PRBool aIgnoreAlign) +{ + PRUint16 align, meetOrSlice; + { + nsCOMPtr par; + aPreserveAspectRatio->GetAnimVal(getter_AddRefs(par)); + NS_ASSERTION(par, "could not get preserveAspectRatio"); + par->GetAlign(&align); + par->GetMeetOrSlice(&meetOrSlice); + } + + // default to the defaults + if (align == nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_UNKNOWN) + align = nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID; + if (meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_UNKNOWN) + meetOrSlice = nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET; + + // alignment disabled for this matrix setup + if (aIgnoreAlign) + align = nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMIN; + + float a, d, e, f; + a = aViewportWidth / aViewboxWidth; + d = aViewportHeight / aViewboxHeight; + e = 0.0f; + f = 0.0f; + + if (align != nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE && + a != d) { + if (meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET && + a < d || + meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE && + d < a) { + d = a; + switch (align) { + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMIN: + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN: + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN: + break; + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID: + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: + f = (aViewportHeight - a * aViewboxHeight) / 2.0f; + break; + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX: + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: + f = aViewportHeight - a * aViewboxHeight; + break; + default: + NS_NOTREACHED("Unknown value for align"); + } + } + else if ( + meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET && + d < a || + meetOrSlice == nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE && + a < d) { + a = d; + switch (align) { + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMIN: + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID: + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX: + break; + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN: + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: + e = (aViewportWidth - a * aViewboxWidth) / 2.0f; + break; + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN: + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: + case nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: + e = aViewportWidth - a * aViewboxWidth; + break; + default: + NS_NOTREACHED("Unknown value for align"); + } + } + else NS_NOTREACHED("Unknown value for meetOrSlice"); + } + + if (aViewboxX) e += -a * aViewboxX; + if (aViewboxY) f += -d * aViewboxY; + + nsIDOMSVGMatrix *retval; + NS_NewSVGMatrix(&retval, a, 0.0f, 0.0f, d, e, f); + return retval; +} diff --git a/layout/svg/base/src/nsSVGUtils.h b/layout/svg/base/src/nsSVGUtils.h index 102e4fc33516..0a3c455f3cb9 100644 --- a/layout/svg/base/src/nsSVGUtils.h +++ b/layout/svg/base/src/nsSVGUtils.h @@ -42,6 +42,7 @@ #include #include "nscore.h" +#include "nsCOMPtr.h" class nsPresContext; class nsIContent; @@ -62,6 +63,7 @@ class nsISVGRendererSurface; class nsIPresShell; class nsISVGRendererCanvas; class nsISVGOuterSVGFrame; +class nsIDOMSVGAnimatedPreserveAspectRatio; #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -205,6 +207,15 @@ public: static nsISVGOuterSVGFrame * GetOuterSVGFrame(nsIFrame *aFrame); + /* Generate a viewbox to viewport tranformation matrix */ + + static already_AddRefed + GetViewBoxTransform(float aViewportWidth, float aViewportHeight, + float aViewboxX, float aViewboxY, + float aViewboxWidth, float aViewboxHeight, + nsIDOMSVGAnimatedPreserveAspectRatio *aPreserveAspectRatio, + PRBool aIgnoreAlign = PR_FALSE); + private: /* * Returns the glyph fragment containing a particular character