cairo: don't leak transforms, also random flailing trying to fix fonts

This commit is contained in:
vladimir%pobox.com 2004-08-18 06:48:20 +00:00
parent 95f06662d3
commit 2509dbd32a
5 changed files with 113 additions and 49 deletions

View File

@ -129,8 +129,6 @@ nsCairoDeviceContext::Init(nsNativeWidget aWidget)
mTwipsToPixels = 96 / (float)NSIntPointsToTwips(72);
mPixelsToTwips = 1.0f / mTwipsToPixels;
//mTwipsToPixels = 1.0f;
//mPixelsToTwips = 1.0f;
mWidget = aWidget;

View File

@ -197,19 +197,38 @@ nsCairoImage::Draw(nsIRenderingContext &aContext, nsIDrawingSurface *aSurface,
cairo_t *dstCairo = cairoContext->GetCairo();
cairo_pattern_t *prepat = cairo_current_pattern (dstCairo);
fprintf (stderr, " IMAGE: pattern: %p ", prepat);
cairo_save(dstCairo);
cairo_set_rgb_color (dstCairo, 1.0, 0.0, 0.0);
#if 0
{
cairo_matrix_t *mat = cairo_matrix_create();
cairo_current_matrix (dstCairo, mat);
double a,b,c,d,tx,ty;
cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty);
fprintf (stderr, " [cur tx ty: %g %g %d %d] ", tx, ty, (int) tx, (int) ty);
}
if (aSWidth == 16 && aSHeight == 16 && aDWidth == 16 && aDHeight == 16)
cairo_set_rgb_color (dstCairo, 0.0, 1.0, 0.0);
else
cairo_set_rgb_color (dstCairo, 1.0, 0.0, 0.0);
cairo_rectangle (dstCairo, double(aDX), double(aDY), double(aDWidth), double(aDHeight));
cairo_fill (dstCairo);
#if 0
cairo_pattern_t *postpat = cairo_current_pattern (dstCairo);
fprintf (stderr, " ---> %p ", postpat);
#else
cairo_pattern_t *imgpat = cairo_pattern_create_for_surface (mImageSurface);
cairo_matrix_t *mat = cairo_matrix_create();
cairo_matrix_translate (mat, double(aSX), double(aSY));
cairo_matrix_scale (mat, 1.0/15.0, 1.0/15.0);
cairo_matrix_scale (mat, double(aDWidth)/double(aSWidth), double(aDHeight)/double(aSHeight));
cairo_matrix_translate (mat, double(aSX), double(aSY));
cairo_pattern_set_matrix (imgpat, mat);
cairo_set_pattern (dstCairo, imgpat);
cairo_new_path (dstCairo);
@ -223,6 +242,8 @@ nsCairoImage::Draw(nsIRenderingContext &aContext, nsIDrawingSurface *aSurface,
cairo_restore(dstCairo);
cairo_pattern_t *endpat = cairo_current_pattern (dstCairo);
fprintf (stderr, " ---> %p\n", endpat);
return NS_OK;
}
@ -248,6 +269,7 @@ nsCairoImage::DrawToImage(nsIImage* aDstImage, PRInt32 aDX, PRInt32 aDY, PRInt32
cairo_pattern_t *pat = cairo_pattern_create_for_surface (mImageSurface);
cairo_matrix_t *mat = cairo_matrix_create ();
cairo_matrix_scale (mat, 1.0/15.0, 1.0/15.0);
cairo_matrix_scale (mat, double(aDWidth)/double(mWidth), double(aDHeight)/double(mHeight));
cairo_pattern_set_matrix (pat, mat);

View File

@ -101,7 +101,7 @@ nsCairoRenderingContext::Init(nsIDeviceContext* aContext, nsIWidget *aWidget)
cairo_select_font (mCairo, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
return NS_OK;
return (CommonInit());
}
NS_IMETHODIMP
@ -124,6 +124,16 @@ nsCairoRenderingContext::Init(nsIDeviceContext* aContext, nsIDrawingSurface *aSu
cairo_select_font (mCairo, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
return (CommonInit());
}
NS_IMETHODIMP
nsCairoRenderingContext::CommonInit(void)
{
float app2dev;
app2dev = mDeviceContext->AppUnitsToDevUnits();
Scale(app2dev, app2dev);
return NS_OK;
}
@ -138,7 +148,7 @@ nsCairoRenderingContext::Reset(void)
mClipRegion = new nsCairoRegion();
return NS_OK;
return (CommonInit());
}
NS_IMETHODIMP
@ -247,11 +257,17 @@ nsCairoRenderingContext::DoCairoClip()
cairo_init_clip (mCairo);
float pixToTwip = mDeviceContext->DevUnitsToTwips();
if (cplx == eRegionComplexity_rect) {
PRInt32 x, y, w, h;
mClipRegion->GetBoundingBox(&x, &y, &w, &h);
cairo_new_path (mCairo);
cairo_rectangle (mCairo, double(x*15), double(y*15), double(w*15), double(h*15));
cairo_rectangle (mCairo,
double(x * pixToTwip),
double(y * pixToTwip),
double(w * pixToTwip),
double(h * pixToTwip));
cairo_clip (mCairo);
} else if (cplx == eRegionComplexity_complex) {
nsRegionRectSet *rects = nsnull;
@ -262,10 +278,10 @@ nsCairoRenderingContext::DoCairoClip()
cairo_new_path (mCairo);
for (PRUint32 i = 0; i < rects->mRectsLen; i++) {
cairo_rectangle (mCairo,
double (rects->mRects[i].x * 15),
double (rects->mRects[i].y * 15),
double (rects->mRects[i].width * 15),
double (rects->mRects[i].height * 15));
double (rects->mRects[i].x * pixToTwip),
double (rects->mRects[i].y * pixToTwip),
double (rects->mRects[i].width * pixToTwip),
double (rects->mRects[i].height * pixToTwip));
}
cairo_clip (mCairo);
@ -312,14 +328,16 @@ nsCairoRenderingContext::SetClipRegion(const nsIRegion& aRegion,
NS_IMETHODIMP
nsCairoRenderingContext::CopyClipRegion(nsIRegion &aRegion)
{
NS_ERROR("not used anywhere");
aRegion.SetTo(*mClipRegion);
return NS_OK;
}
NS_IMETHODIMP
nsCairoRenderingContext::GetClipRegion(nsIRegion **aRegion)
{
NS_ERROR("not used anywhere");
*aRegion = new nsCairoRegion();
(*aRegion)->SetTo(*mClipRegion);
NS_ADDREF(*aRegion);
return NS_OK;
}
@ -420,6 +438,7 @@ nsCairoRenderingContext::GetColor(nscolor &aColor) const
NS_IMETHODIMP
nsCairoRenderingContext::Translate(nscoord aX, nscoord aY)
{
fprintf (stderr, "++ Xlate: %g %g\n", (double)aX, (double)aY);
cairo_translate (mCairo, (double) aX, (double) aY);
return NS_OK;
}
@ -427,43 +446,59 @@ nsCairoRenderingContext::Translate(nscoord aX, nscoord aY)
NS_IMETHODIMP
nsCairoRenderingContext::Scale(float aSx, float aSy)
{
// fprintf (stderr, "++ Scale: %g %g\n", (double)aSx, (double)aSy);
cairo_scale (mCairo, (double) aSx, (double) aSy);
return NS_OK;
}
void
nsCairoRenderingContext::UpdateTempTransformMatrix()
{
double a, b, c, d, tx, ty;
cairo_matrix_t *mat = cairo_matrix_create();
cairo_current_matrix (mCairo, mat);
cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty);
/*****
* Cairo matrix layout: gfx matrix layout:
* | a b 0 | | m00 m01 0 |
* | c d 0 | | m10 m11 0 |
* | tx ty 1 | | m20 m21 1 |
*****/
cairo_matrix_destroy (mat);
if (tx == ty == 0.0 &&
b == c == 0.0)
{
mTempTransform.SetToScale (a, d);
} else if (b == c == 0.0 &&
a == d == 1.0)
{
mTempTransform.SetToTranslate (tx, ty);
} else {
/* XXX we need to add api on nsTransform2D to set all these values since they are private */
mTempTransform.m00 = a;
mTempTransform.m01 = b;
mTempTransform.m10 = c;
mTempTransform.m11 = d;
mTempTransform.m20 = tx;
mTempTransform.m21 = ty;
mTempTransform.type = MG_2DGENERAL;
}
}
nsTransform2D&
nsCairoRenderingContext::CurrentTransform()
{
UpdateTempTransformMatrix();
return mTempTransform;
}
NS_IMETHODIMP
nsCairoRenderingContext::GetCurrentTransform(nsTransform2D *&aTransform)
{
printf("getcurrenttrasnform()\n");
double a, b, c, d, tx, ty;
cairo_matrix_t *mat = cairo_matrix_create();
cairo_current_matrix (mCairo, mat);
cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty);
cairo_matrix_destroy (mat);
aTransform = new nsTransform2D;
if (tx == ty == 0.0 &&
b == c == 0.0)
{
aTransform->SetToScale (a, d);
} else if (b == c == 0.0 &&
a == d == 1.0)
{
aTransform->SetToTranslate (tx, ty);
} else {
aTransform->Set(a, b, c, d, tx, ty, MG_2DGENERAL);
/* XXX we need to add api on nsTransform2D to set all these values since they are private
aTransform->m00 = a;
aTransform->m01 = b;
aTransform->m10 = c;
aTransform->m11 = d;
aTransform->m20 = tx;
aTransform->m21 = ty;
aTransform->type = MG_2DGENERAL;
*/
}
UpdateTempTransformMatrix();
aTransform = &mTempTransform;
return NS_OK;
}
@ -757,11 +792,15 @@ nsCairoRenderingContext::GetBackbuffer(const nsRect &aRequestedSize,
nsIDrawingSurface* &aBackbuffer)
{
if (!mBackBufferSurface) {
#if 1
nsIDeviceContext *dc = mDeviceContext.get();
mBackBufferSurface = new nsCairoDrawingSurface ();
mBackBufferSurface->Init (NS_STATIC_CAST(nsCairoDeviceContext*, dc),
aMaxSize.width, aMaxSize.height,
PR_FALSE);
#else
mBackBufferSurface = mDrawingSurface;
#endif
}
aBackbuffer = mBackBufferSurface;

View File

@ -67,6 +67,7 @@ public:
NS_IMETHOD Init(nsIDeviceContext* aContext, nsIWidget *aWidget);
NS_IMETHOD Init(nsIDeviceContext* aContext, nsIDrawingSurface *aSurface);
NS_IMETHOD CommonInit(void);
NS_IMETHOD Reset(void);
NS_IMETHOD GetDeviceContext(nsIDeviceContext *& aDeviceContext);
NS_IMETHOD LockDrawingSurface(PRInt32 aX, PRInt32 aY,
@ -202,6 +203,8 @@ public:
cairo_t *GetCairo() { return mCairo; }
nsTransform2D& CurrentTransform();
protected:
PRBool DoCairoDrawPolygon(const nsPoint aPoints[], PRInt32 aNumPoints);
void DoCairoDrawEllipse (double aX, double aY, double aWidth, double aHeight);
@ -225,6 +228,10 @@ protected:
nsCOMPtr<nsCairoDrawingSurface> mDrawingSurface;
nsCOMPtr<nsCairoDrawingSurface> mOffscreenSurface;
nsCOMPtr<nsCairoDrawingSurface> mBackBufferSurface;
// for handing out to people
void UpdateTempTransformMatrix();
nsTransform2D mTempTransform;
};
#endif // NSCAIRORENDERINGCONTEXT__H__

View File

@ -1532,8 +1532,7 @@ nsFontMetricsXft::DrawStringCallback(const FcChar32 *aString, PRUint32 aLen,
nscoord y = data->y;
// convert this into device coordinates
// XXX pavlov ugh...
//data->context->GetTranMatrix()->TransformCoord(&x, &y);
data->context->CurrentTransform().TransformCoord(&x, &y);
DrawUnknownGlyph(ch, x, y + mMiniFontYOffset, &data->color,
data->draw);
@ -2005,8 +2004,7 @@ nsFontXft::DrawStringSpec(FcChar32 *aString, PRUint32 aLen, void *aData)
nscoord x = data->x + data->xOffset;
nscoord y = data->y;
/* Convert to device coordinate. */
// XXX pavlov ugh..
//data->context->GetTranMatrix()->TransformCoord(&x, &y);
data->context->CurrentTransform().TransformCoord(&x, &y);
/* position in X is the location offset in the string
plus whatever offset is required for the spacing