Bug 290432. Add push/pop translation functions to nsIRenderingContext so cairo can override them. r+sr=bzbarsky,a=asa

This commit is contained in:
roc+%cs.cmu.edu 2005-04-19 22:58:33 +00:00
parent df9ef8a155
commit 9062a6ea25
5 changed files with 70 additions and 42 deletions

View File

@ -313,6 +313,28 @@ public:
*/
NS_IMETHOD Scale(float aSx, float aSy) = 0;
struct PushedTranslation {
float mSavedX, mSavedY;
};
class AutoPushTranslation {
nsIRenderingContext* mCtx;
PushedTranslation mPushed;
public:
AutoPushTranslation(nsIRenderingContext* aCtx, nscoord aX, nscoord aY)
: mCtx(aCtx) {
mCtx->PushTranslation(&mPushed);
mCtx->Translate(aX, aY);
}
~AutoPushTranslation() {
mCtx->PopTranslation(&mPushed);
}
};
NS_IMETHOD PushTranslation(PushedTranslation* aState) = 0;
NS_IMETHOD PopTranslation(PushedTranslation* aState) = 0;
/**
* Get the current transformation matrix for the RenderingContext
* @return The transformation matrix for the RenderingContext

View File

@ -95,6 +95,9 @@ public:
NS_IMETHOD DestroyCachedBackbuffer(void);
NS_IMETHOD UseBackbuffer(PRBool* aUseBackbuffer);
NS_IMETHOD PushTranslation(PushedTranslation* aState);
NS_IMETHOD PopTranslation(PushedTranslation* aState);
/**
* Let the device context know whether we want text reordered with
* right-to-left base direction

View File

@ -151,6 +151,38 @@ NS_IMETHODIMP nsRenderingContextImpl::UseBackbuffer(PRBool* aUseBackbuffer)
return NS_OK;
}
NS_IMETHODIMP nsRenderingContextImpl::PushTranslation(PushedTranslation* aState)
{
// The transform components are saved and restored instead
// of using PushState and PopState because they are too slow
// because they also save and restore the clip state.
// Note: Setting a negative translation to restore the
// state does not work because the floating point errors can accumulate
// causing the display of some frames to be off by one pixel.
// This happens frequently when running in 120DPI mode where frames are
// often positioned at 1/2 pixel locations and small floating point errors
// will cause the frames to vary their pixel x location during scrolling
// operations causes a single scan line of pixels to be shifted left relative
// to the other scan lines for the same text.
// Save the transformation matrix's translation components.
nsTransform2D *theTransform;
GetCurrentTransform(theTransform);
NS_ASSERTION(theTransform != nsnull, "The rendering context transform is null");
theTransform->GetTranslation(&aState->mSavedX, &aState->mSavedY);
return NS_OK;
}
NS_IMETHODIMP nsRenderingContextImpl::PopTranslation(PushedTranslation* aState)
{
nsTransform2D *theTransform;
GetCurrentTransform(theTransform);
NS_ASSERTION(theTransform != nsnull, "The rendering context transform is null");
theTransform->SetTranslation(aState->mSavedX, aState->mSavedY);
return NS_OK;
}
PRBool nsRenderingContextImpl::RectFitsInside(const nsRect& aRect, PRInt32 aWidth, PRInt32 aHeight) const
{

View File

@ -274,34 +274,13 @@ nsContainerFrame::PaintChild(nsPresContext* aPresContext,
damageArea.x -= kidRect.x;
damageArea.y -= kidRect.y;
// The transform components are saved and restored instead
// of using PushState and PopState because they are too slow
// because they also save and restore the clip state.
// Note: Setting a negative translation to restore the
// state does not work because the floating point errors can accumulate
// causing the display of some frames to be off by one pixel.
// This happens frequently when running in 120DPI mode where frames are
// often positioned at 1/2 pixel locations and small floating point errors
// will cause the frames to vary their pixel x location during scrolling
// operations causes a single scan line of pixels to be shifted left relative
// to the other scan lines for the same text.
// Save the transformation matrix's translation components.
float xMatrix;
float yMatrix;
nsTransform2D *theTransform;
aRenderingContext.GetCurrentTransform(theTransform);
NS_ASSERTION(theTransform != nsnull, "The rendering context transform is null");
theTransform->GetTranslation(&xMatrix, &yMatrix);
aRenderingContext.Translate(kidRect.x, kidRect.y);
// Paint the kid
aFrame->Paint(aPresContext, aRenderingContext, damageArea, aWhichLayer, aFlags);
// Restore the transformation matrix's translation components.
theTransform->SetTranslation(xMatrix, yMatrix);
{
nsIRenderingContext::AutoPushTranslation
translate(&aRenderingContext, kidRect.x, kidRect.y);
// Paint the kid
aFrame->Paint(aPresContext, aRenderingContext, damageArea, aWhichLayer, aFlags);
}
#ifdef NS_DEBUG
// Draw a border around the child

View File

@ -1465,21 +1465,13 @@ nsBoxFrame::PaintChild(nsPresContext* aPresContext,
damageArea.x -= kidRect.x;
damageArea.y -= kidRect.y;
// Save the transformation matrix's translation components.
float xMatrix;
float yMatrix;
nsTransform2D *theTransform;
aRenderingContext.GetCurrentTransform(theTransform);
NS_ASSERTION(theTransform != nsnull, "The rendering context transform is null");
theTransform->GetTranslation(&xMatrix, &yMatrix);
{
nsIRenderingContext::AutoPushTranslation
translate(&aRenderingContext, kidRect.x, kidRect.y);
aRenderingContext.Translate(kidRect.x, kidRect.y);
// Paint the kid
aFrame->Paint(aPresContext, aRenderingContext, damageArea, aWhichLayer);
// Restore the transformation matrix's translation components.
theTransform->SetTranslation(xMatrix, yMatrix);
// Paint the kid
aFrame->Paint(aPresContext, aRenderingContext, damageArea, aWhichLayer);
}
}
}
}