Bug 370006 - svg doesn't get scaled up on high resolution displays. r=jwatt, sr=roc

This commit is contained in:
tor@cs.brown.edu 2007-12-03 20:40:52 -08:00
Родитель 4d6e56edaa
Коммит a79c52724d
12 изменённых файлов: 90 добавлений и 66 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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;

Просмотреть файл

@ -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<nsIDOMSVGRect> 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<nsIDOMSVGMatrix> 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);
}

Просмотреть файл

@ -54,6 +54,7 @@ protected:
nsSVGContainerFrameBase(aContext) {}
public:
// Returns the transform to our gfxContext (to device pixels, not CSS px)
virtual already_AddRefed<nsIDOMSVGMatrix> GetCanvasTM() { return nsnull; }
// nsIFrame:

Просмотреть файл

@ -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);
/**

Просмотреть файл

@ -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<nsIDOMSVGMatrix> 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);

Просмотреть файл

@ -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();

Просмотреть файл

@ -242,35 +242,10 @@ nsSVGMaskFrame::GetCanvasTM()
{
NS_ASSERTION(mMaskParentMatrix, "null parent matrix");
nsCOMPtr<nsIDOMSVGMatrix> canvasTM = mMaskParentMatrix;
/* object bounding box? */
nsSVGMaskElement *mask = static_cast<nsSVGMaskElement*>(mContent);
PRUint16 contentUnits =
mask->mEnumAttributes[nsSVGMaskElement::MASKCONTENTUNITS].GetAnimValue();
if (mMaskParent &&
contentUnits == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
nsCOMPtr<nsIDOMSVGRect> 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<nsIDOMSVGMatrix> 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);
}

Просмотреть файл

@ -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<nsSVGSVGElement*>(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<nsIDOMSVGMatrix>
nsSVGOuterSVGFrame::GetCanvasTM()
{
if (!mCanvasTM) {
nsCOMPtr<nsIDOMSVGMatrix> vb2vp;
nsSVGSVGElement *svgElement = static_cast<nsSVGSVGElement*>(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

Просмотреть файл

@ -168,6 +168,8 @@ protected:
nsCOMPtr<nsIDOMSVGPoint> mCurrentTranslate;
nsCOMPtr<nsIDOMSVGNumber> mCurrentScale;
float mFullZoom;
PRPackedBool mViewportInitialized;
};

Просмотреть файл

@ -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<nsIDOMSVGMatrix>
nsSVGUtils::AdjustMatrixForUnits(nsIDOMSVGMatrix *aMatrix,
nsSVGEnum *aUnits,
nsISVGChildFrame *aFrame)
{
nsCOMPtr<nsIDOMSVGMatrix> fini = aMatrix;
if (aFrame &&
aUnits->GetAnimValue() == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
nsCOMPtr<nsIDOMSVGRect> 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<nsIDOMSVGMatrix> 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)

Просмотреть файл

@ -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<nsIDOMSVGMatrix>
AdjustMatrixForUnits(nsIDOMSVGMatrix *aMatrix,
nsSVGEnum *aUnits,
nsISVGChildFrame *aFrame);
#ifdef DEBUG
static void
WritePPM(const char *fname, gfxImageSurface *aSurface);