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*
|
ServerBitmap*
|
||||||
AlphaMask::_RenderPicture() const
|
AlphaMask::_RenderPicture() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ public:
|
|||||||
void SetPrevious(AlphaMask* mask);
|
void SetPrevious(AlphaMask* mask);
|
||||||
|
|
||||||
scanline_unpacked_masked_type* Generate();
|
scanline_unpacked_masked_type* Generate();
|
||||||
|
agg::clipped_alpha_mask* Mask();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ServerBitmap* _RenderPicture() const;
|
ServerBitmap* _RenderPicture() const;
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ using std::nothrow;
|
|||||||
#define fSubpixRasterizer fInternal.fSubpixRasterizer
|
#define fSubpixRasterizer fInternal.fSubpixRasterizer
|
||||||
#define fSubpixRenderer fInternal.fSubpixRenderer
|
#define fSubpixRenderer fInternal.fSubpixRenderer
|
||||||
#define fMaskedUnpackedScanline fInternal.fMaskedUnpackedScanline
|
#define fMaskedUnpackedScanline fInternal.fMaskedUnpackedScanline
|
||||||
|
#define fClippedAlphaMask fInternal.fClippedAlphaMask
|
||||||
#define fPath fInternal.fPath
|
#define fPath fInternal.fPath
|
||||||
#define fCurve fInternal.fCurve
|
#define fCurve fInternal.fCurve
|
||||||
|
|
||||||
@@ -287,10 +288,13 @@ Painter::SetDrawState(const DrawState* state, int32 xOffset, int32 yOffset)
|
|||||||
|
|
||||||
fSubpixelPrecise = state->SubPixelPrecise();
|
fSubpixelPrecise = state->SubPixelPrecise();
|
||||||
|
|
||||||
if (state->GetAlphaMask() != NULL)
|
if (state->GetAlphaMask() != NULL) {
|
||||||
fMaskedUnpackedScanline = state->GetAlphaMask()->Generate();
|
fMaskedUnpackedScanline = state->GetAlphaMask()->Generate();
|
||||||
else
|
fClippedAlphaMask = state->GetAlphaMask()->Mask();
|
||||||
|
} else {
|
||||||
fMaskedUnpackedScanline = NULL;
|
fMaskedUnpackedScanline = NULL;
|
||||||
|
fClippedAlphaMask = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// any of these conditions means we need to use a different drawing
|
// any of these conditions means we need to use a different drawing
|
||||||
// mode instance
|
// mode instance
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ struct PainterAggInterface {
|
|||||||
fSubpixRasterizer(),
|
fSubpixRasterizer(),
|
||||||
fSubpixRenderer(fBaseRenderer),
|
fSubpixRenderer(fBaseRenderer),
|
||||||
fMaskedUnpackedScanline(NULL),
|
fMaskedUnpackedScanline(NULL),
|
||||||
|
fClippedAlphaMask(NULL),
|
||||||
fPath(),
|
fPath(),
|
||||||
fCurve(fPath)
|
fCurve(fPath)
|
||||||
{
|
{
|
||||||
@@ -58,6 +59,7 @@ struct PainterAggInterface {
|
|||||||
// Alpha-Masked mode: for ClipToPicture
|
// Alpha-Masked mode: for ClipToPicture
|
||||||
// (this uses the standard rasterizer and renderer)
|
// (this uses the standard rasterizer and renderer)
|
||||||
scanline_unpacked_masked_type* fMaskedUnpackedScanline;
|
scanline_unpacked_masked_type* fMaskedUnpackedScanline;
|
||||||
|
agg::clipped_alpha_mask* fClippedAlphaMask;
|
||||||
|
|
||||||
agg::path_storage fPath;
|
agg::path_storage fPath;
|
||||||
agg::conv_curve<agg::path_storage> fCurve;
|
agg::conv_curve<agg::path_storage> fCurve;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace agg
|
|||||||
public:
|
public:
|
||||||
typedef int8u cover_type;
|
typedef int8u cover_type;
|
||||||
enum cover_scale_e
|
enum cover_scale_e
|
||||||
{
|
{
|
||||||
cover_shift = 8,
|
cover_shift = 8,
|
||||||
cover_none = 0,
|
cover_none = 0,
|
||||||
cover_full = 255
|
cover_full = 255
|
||||||
@@ -44,46 +44,13 @@ namespace agg
|
|||||||
|
|
||||||
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
|
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;
|
int count = num_pix;
|
||||||
cover_type* covers = dst;
|
cover_type* covers = dst;
|
||||||
|
|
||||||
if(y < 0 || y > ymax)
|
bool has_inside = _set_outside(x, y, covers, count);
|
||||||
{
|
if (!has_inside)
|
||||||
memset(dst, m_outside, num_pix * sizeof(cover_type));
|
|
||||||
return;
|
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;
|
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -95,6 +62,67 @@ namespace agg
|
|||||||
while(--count);
|
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:
|
private:
|
||||||
int m_xOffset;
|
int m_xOffset;
|
||||||
int m_yOffset;
|
int m_yOffset;
|
||||||
|
|||||||
Reference in New Issue
Block a user