Use PushGroup()/PopGroup() to implement transparency blending using cairo

This commit is contained in:
vladimir%pobox.com 2006-01-18 22:43:42 +00:00
Родитель 861a6a1bf7
Коммит 19a40b2ba3
5 изменённых файлов: 50 добавлений и 10 удалений

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

@ -849,23 +849,30 @@ NS_IMETHODIMP
nsThebesRenderingContext::PushFilter(const nsRect& twRect, PRBool aAreaIsOpaque, float aOpacity)
{
gfxPoint p0(FROM_TWIPS(twRect.x), FROM_TWIPS(twRect.y));
gfxPoint p1(FROM_TWIPS(twRect.XMost()), FROM_TWIPS(twRect.YMost()));
gfxSize ps(FROM_TWIPS(twRect.XMost() - twRect.x),
FROM_TWIPS(twRect.YMost() - twRect.y));
p0 = mThebes->UserToDevice(p0);
p1 = mThebes->UserToDevice(p1);
mOpacityArray.AppendElement(aOpacity);
nsIntRect deviceRect(TO_TWIPS(floor(PR_MIN(p0.x, p1.x))),
TO_TWIPS(floor(PR_MIN(p0.y, p1.y))),
TO_TWIPS(ceil(PR_MAX(p0.x, p1.x))),
TO_TWIPS(ceil(PR_MAX(p0.y, p1.y))));
return mDrawingSurface->PushFilter(deviceRect, aAreaIsOpaque, aOpacity);
mThebes->Save();
mThebes->Clip(gfxRect(p0, ps));
mThebes->PushGroup();
return NS_OK;
}
NS_IMETHODIMP
nsThebesRenderingContext::PopFilter()
{
mDrawingSurface->PopFilter();
if (mOpacityArray.Length() > 0) {
float f = mOpacityArray[mOpacityArray.Length()-1];
mOpacityArray.RemoveElementAt(mOpacityArray.Length()-1);
mThebes->PopGroupToSource();
mThebes->Paint(f);
}
mThebes->Restore();
return NS_OK;
}

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

@ -40,6 +40,7 @@
#define NSTHEBESRENDERINGCONTEXT__H__
#include "nsCOMPtr.h"
#include "nsTArray.h"
#include "nsIRenderingContext.h"
#include "nsRenderingContextImpl.h"
#include "nsIDeviceContext.h"
@ -273,6 +274,9 @@ protected:
// for handing out to people
void UpdateTempTransformMatrix();
nsTransform2D mTempTransform;
// keeping track of pushgroup/popgroup opacities
nsTArray<float> mOpacityArray;
};
#endif // NSCAIRORENDERINGCONTEXT__H__

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

@ -477,6 +477,13 @@ public:
void Clip(gfxRect rect); // will clip to a rect
void Clip(const gfxRegion& region); // will clip to a region
/**
* Groups
*/
void PushGroup();
gfxPattern *PopGroup();
void PopGroupToSource();
/**
** Filters/Group Rendering
** XXX these aren't really "filters" and should be renamed properly.

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

@ -45,7 +45,11 @@
#include "gfxMatrix.h"
#include "gfxTypes.h"
class gfxContext;
class NS_EXPORT gfxPattern {
friend class gfxContext;
THEBES_DECL_REFCOUNTING
public:

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

@ -497,6 +497,24 @@ void gfxContext::Paint(gfxFloat alpha)
cairo_paint_with_alpha(mCairo, alpha);
}
// groups
void gfxContext::PushGroup()
{
cairo_push_group(mCairo);
}
gfxPattern *gfxContext::PopGroup()
{
cairo_pattern_t *pat = cairo_pop_group(mCairo);
return new gfxPattern(pat);
}
void gfxContext::PopGroupToSource()
{
cairo_pop_group_to_source(mCairo);
}
// filters
void gfxContext::PushFilter(gfxFilter& filter, FilterHints hints, gfxRect& maxArea)
{