app_server: give Painter direct access to alpha masks
* To use alpha masks in optimized drawing code outside of the AGG
renderer pipeline, we need to allow access to the alpha mask's
underlying buffer:
- AlphaMask gets another method which returns its
clipped_alpha_mask
- clipped_alpha_mask gets a get_hspan() method which returns a span
of alpha values without combining it with anything
- Painter/PainterAggInterface store a pointer to the
clipped_alpha_mask (in addition to the AlphaMask's scanline
container)
This commit is contained in:
@@ -220,6 +220,13 @@ AlphaMask::Generate()
|
||||
}
|
||||
|
||||
|
||||
agg::clipped_alpha_mask*
|
||||
AlphaMask::Mask()
|
||||
{
|
||||
return &fCachedMask;
|
||||
}
|
||||
|
||||
|
||||
ServerBitmap*
|
||||
AlphaMask::_RenderPicture() const
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
void SetPrevious(AlphaMask* mask);
|
||||
|
||||
scanline_unpacked_masked_type* Generate();
|
||||
agg::clipped_alpha_mask* Mask();
|
||||
|
||||
private:
|
||||
ServerBitmap* _RenderPicture() const;
|
||||
|
||||
@@ -102,6 +102,7 @@ using std::nothrow;
|
||||
#define fSubpixRasterizer fInternal.fSubpixRasterizer
|
||||
#define fSubpixRenderer fInternal.fSubpixRenderer
|
||||
#define fMaskedUnpackedScanline fInternal.fMaskedUnpackedScanline
|
||||
#define fClippedAlphaMask fInternal.fClippedAlphaMask
|
||||
#define fPath fInternal.fPath
|
||||
#define fCurve fInternal.fCurve
|
||||
|
||||
@@ -287,10 +288,13 @@ Painter::SetDrawState(const DrawState* state, int32 xOffset, int32 yOffset)
|
||||
|
||||
fSubpixelPrecise = state->SubPixelPrecise();
|
||||
|
||||
if (state->GetAlphaMask() != NULL)
|
||||
if (state->GetAlphaMask() != NULL) {
|
||||
fMaskedUnpackedScanline = state->GetAlphaMask()->Generate();
|
||||
else
|
||||
fClippedAlphaMask = state->GetAlphaMask()->Mask();
|
||||
} else {
|
||||
fMaskedUnpackedScanline = NULL;
|
||||
fClippedAlphaMask = NULL;
|
||||
}
|
||||
|
||||
// any of these conditions means we need to use a different drawing
|
||||
// mode instance
|
||||
|
||||
@@ -29,6 +29,7 @@ struct PainterAggInterface {
|
||||
fSubpixRasterizer(),
|
||||
fSubpixRenderer(fBaseRenderer),
|
||||
fMaskedUnpackedScanline(NULL),
|
||||
fClippedAlphaMask(NULL),
|
||||
fPath(),
|
||||
fCurve(fPath)
|
||||
{
|
||||
@@ -58,6 +59,7 @@ struct PainterAggInterface {
|
||||
// Alpha-Masked mode: for ClipToPicture
|
||||
// (this uses the standard rasterizer and renderer)
|
||||
scanline_unpacked_masked_type* fMaskedUnpackedScanline;
|
||||
agg::clipped_alpha_mask* fClippedAlphaMask;
|
||||
|
||||
agg::path_storage fPath;
|
||||
agg::conv_curve<agg::path_storage> fCurve;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace agg
|
||||
public:
|
||||
typedef int8u cover_type;
|
||||
enum cover_scale_e
|
||||
{
|
||||
{
|
||||
cover_shift = 8,
|
||||
cover_none = 0,
|
||||
cover_full = 255
|
||||
@@ -44,46 +44,13 @@ namespace agg
|
||||
|
||||
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
x -= m_xOffset;
|
||||
y -= m_yOffset;
|
||||
|
||||
int xmax = m_rbuf->width() - 1;
|
||||
int ymax = m_rbuf->height() - 1;
|
||||
|
||||
int count = num_pix;
|
||||
cover_type* covers = dst;
|
||||
|
||||
if(y < 0 || y > ymax)
|
||||
{
|
||||
memset(dst, m_outside, num_pix * sizeof(cover_type));
|
||||
bool has_inside = _set_outside(x, y, covers, count);
|
||||
if (!has_inside)
|
||||
return;
|
||||
}
|
||||
|
||||
if(x < 0)
|
||||
{
|
||||
count += x;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, m_outside, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
memset(covers, m_outside, -x * sizeof(cover_type));
|
||||
covers -= x;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if(x + count > xmax)
|
||||
{
|
||||
int rest = x + count - xmax - 1;
|
||||
count -= rest;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, m_outside, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
memset(covers + count, m_outside, rest * sizeof(cover_type));
|
||||
}
|
||||
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
do
|
||||
{
|
||||
@@ -95,6 +62,67 @@ namespace agg
|
||||
while(--count);
|
||||
}
|
||||
|
||||
void get_hspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
int count = num_pix;
|
||||
cover_type* covers = dst;
|
||||
|
||||
bool has_inside = _set_outside(x, y, covers, count);
|
||||
if (!has_inside)
|
||||
return;
|
||||
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
memcpy(covers, mask, count);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _set_outside(int& x, int& y, cover_type*& covers,
|
||||
int& count) const
|
||||
{
|
||||
x -= m_xOffset;
|
||||
y -= m_yOffset;
|
||||
|
||||
int xmax = m_rbuf->width() - 1;
|
||||
int ymax = m_rbuf->height() - 1;
|
||||
|
||||
int num_pix = count;
|
||||
cover_type* dst = covers;
|
||||
|
||||
if(y < 0 || y > ymax)
|
||||
{
|
||||
memset(dst, m_outside, num_pix * sizeof(cover_type));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(x < 0)
|
||||
{
|
||||
count += x;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, m_outside, num_pix * sizeof(cover_type));
|
||||
return false;
|
||||
}
|
||||
memset(covers, m_outside, -x * sizeof(cover_type));
|
||||
covers -= x;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if(x + count > xmax)
|
||||
{
|
||||
int rest = x + count - xmax - 1;
|
||||
count -= rest;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, m_outside, num_pix * sizeof(cover_type));
|
||||
return false;
|
||||
}
|
||||
memset(covers + count, m_outside, rest * sizeof(cover_type));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
int m_xOffset;
|
||||
int m_yOffset;
|
||||
|
||||
Reference in New Issue
Block a user