Skip to content

Commit

Permalink
add mask owner draw with canvas
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangjipeng committed Jan 6, 2025
1 parent 7b002d9 commit 585d4f5
Show file tree
Hide file tree
Showing 15 changed files with 223 additions and 65 deletions.
4 changes: 2 additions & 2 deletions build/configs.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ elseif (UNIX AND NOT APPLE)
endif()
set(CMAKE_C_FLAGS_DEBUG "-D_DEBUG -O0 -Wall -g -Wno-unused-result ${SANITIZE}")
set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -O0 -Wall -g -std=c++11 -fno-rtti -fno-exceptions -Wno-unused-result -Wno-register -Wno-attributes ${SANITIZE}")
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O3 -Wall -Wno-unused-result")
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -Wall -std=c++11 -fno-rtti -fno-exceptions -Wno-unused-result -Wno-register -Wno-attributes")
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O3 -Wall -Wno-unused-result ${SANITIZE}")
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -Wall -std=c++11 -fno-rtti -fno-exceptions -Wno-unused-result -Wno-register -Wno-attributes ${SANITIZE}")
elseif (APPLE)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
Expand Down
50 changes: 42 additions & 8 deletions include/picasso.h
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ typedef enum _ps_color_format {
* \note To get extended error information, call \a ps_last_status.
*
* \sa ps_canvas_create_with_data, ps_canvas_create_compatible, ps_canvas_create_from_canvas,
* ps_canvas_create_from_image, ps_canvas_ref, ps_canvas_unref
* ps_canvas_create_from_image, ps_canvas_create_from_mask, ps_canvas_ref, ps_canvas_unref
*/
PEXPORT ps_canvas* PICAPI ps_canvas_create(ps_color_format fmt, int width, int height);

Expand All @@ -469,7 +469,7 @@ PEXPORT ps_canvas* PICAPI ps_canvas_create(ps_color_format fmt, int width, int h
* \note To get extended error information, call \a ps_last_status.
*
* \sa ps_canvas_create, ps_canvas_create_compatible, ps_canvas_create_from_canvas,
* ps_canvas_create_from_image, ps_canvas_ref, ps_canvas_unref, ps_canvas_replace_data
* ps_canvas_create_from_image, ps_canvas_create_from_mask, ps_canvas_ref, ps_canvas_unref, ps_canvas_replace_data
*/
PEXPORT ps_canvas* PICAPI ps_canvas_create_with_data(ps_byte* data, ps_color_format fmt,
int width, int height, int pitch);
Expand All @@ -490,7 +490,7 @@ PEXPORT ps_canvas* PICAPI ps_canvas_create_with_data(ps_byte* data, ps_color_for
* \note To get extended error information, call \a ps_last_status.
*
* \sa ps_canvas_create, ps_canvas_create_with_data, ps_canvas_create_from_canvas,
* ps_canvas_create_from_image, ps_canvas_ref, ps_canvas_unref
* ps_canvas_create_from_image, ps_canvas_create_from_mask, ps_canvas_ref, ps_canvas_unref
*/
PEXPORT ps_canvas* PICAPI ps_canvas_create_compatible(const ps_canvas* canvas,
int width, int height);
Expand All @@ -509,7 +509,7 @@ PEXPORT ps_canvas* PICAPI ps_canvas_create_compatible(const ps_canvas* canvas,
* \note To get extended error information, call \a ps_last_status.
*
* \sa ps_canvas_create, ps_canvas_create_with_data, ps_canvas_create_compatible,
* ps_canvas_create_from_image, ps_canvas_ref, ps_canvas_unref
* ps_canvas_create_from_image, ps_canvas_create_from_mask, ps_canvas_ref, ps_canvas_unref
*/
PEXPORT ps_canvas* PICAPI ps_canvas_create_from_canvas(ps_canvas* canvas, const ps_rect* rect);

Expand All @@ -527,10 +527,28 @@ PEXPORT ps_canvas* PICAPI ps_canvas_create_from_canvas(ps_canvas* canvas, const
* \note To get extended error information, call \a ps_last_status.
*
* \sa ps_canvas_create, ps_canvas_create_with_data, ps_canvas_create_compatible,
* ps_canvas_create_from_canvas, ps_canvas_ref, ps_canvas_unref
* ps_canvas_create_from_canvas, ps_canvas_create_from_mask, ps_canvas_ref, ps_canvas_unref
*/
PEXPORT ps_canvas* PICAPI ps_canvas_create_from_image(ps_image* img, const ps_rect* rect);

/**
* \fn ps_canvas* ps_canvas_create_from_mask(ps_image* img, const ps_rect* rect)
* \brief Create a new canvas using part of an existing ps_mask object in same pixel buffer.
*
* \param mask A pointer to an existing ps_mask object.
* \param rect The rectangle area of the canvas from the ps_mask.
* If it is NULL, the canvas's width and height will be equal to ps_mask object.
*
* \return If the function succeeds, the return value is the pointer to a new canvas object.
* If the function fails, the return value is NULL.
*
* \note To get extended error information, call \a ps_last_status.
*
* \sa ps_canvas_create, ps_canvas_create_with_data, ps_canvas_create_compatible,
* ps_canvas_create_from_canvas, ps_canvas_create_from_image, ps_canvas_ref, ps_canvas_unref
*/
PEXPORT ps_canvas* PICAPI ps_canvas_create_from_mask(ps_mask* mask, const ps_rect* rect);

/**
* \fn ps_canvas* PICAPI ps_canvas_replace_data(ps_canvas* canvas, ps_byte* data,
* ps_color_format fmt, int width, int height, int pitch);
Expand Down Expand Up @@ -1088,6 +1106,22 @@ PEXPORT void PICAPI ps_gradient_clear_color_stops(ps_gradient* gradient);
* @{
*/

/**
* \fn ps_mask* ps_mask_create(int width, int height)
* \brief Create a new mask.
*
* \param width The width, in pixels, of the required mask.
* \param height The height, in pixels, of the required mask.
*
* \return If the function succeeds, the return value is the pointer to a new mask object.
* If the function fails, the return value is NULL.
*
* \note To get extended error information, call \a ps_last_status.
*
* \sa ps_mask_ref, ps_mask_unref, ps_canvas_set_mask, ps_canvas_reset_mask, ps_mask_create_with_data
*/
PEXPORT ps_mask* PICAPI ps_mask_create(int width, int height);

/**
* \fn ps_mask* ps_mask_create_with_data(ps_byte* data, int width, int height)
* \brief Create a new mask using a given data block.
Expand All @@ -1103,7 +1137,7 @@ PEXPORT void PICAPI ps_gradient_clear_color_stops(ps_gradient* gradient);
*
* \note To get extended error information, call \a ps_last_status.
*
* \sa ps_mask_ref, ps_mask_unref, ps_canvas_set_mask, ps_canvas_reset_mask
* \sa ps_mask_ref, ps_mask_unref, ps_canvas_set_mask, ps_canvas_reset_mask, ps_mask_create
*/
PEXPORT ps_mask* PICAPI ps_mask_create_with_data(ps_byte* data, int width, int height);

Expand All @@ -1118,7 +1152,7 @@ PEXPORT ps_mask* PICAPI ps_mask_create_with_data(ps_byte* data, int width, int h
*
* \note To get extended error information, call \a ps_last_status.
*
* \sa ps_mask_create_with_data, ps_mask_unref, ps_canvas_set_mask, ps_canvas_reset_mask
* \sa ps_mask_create_with_data, ps_mask_unref, ps_canvas_set_mask, ps_canvas_reset_mask, ps_mask_create
*/
PEXPORT ps_mask* PICAPI ps_mask_ref(ps_mask* mask);

Expand All @@ -1129,7 +1163,7 @@ PEXPORT ps_mask* PICAPI ps_mask_ref(ps_mask* mask);
*
* \param mask Pointer to an existing mask object.
*
* \sa ps_mask_create_with_data, ps_mask_ref, ps_canvas_set_mask, ps_canvas_reset_mask
* \sa ps_mask_create_with_data, ps_mask_ref, ps_canvas_set_mask, ps_canvas_reset_mask, ps_mask_create
*/
PEXPORT void PICAPI ps_mask_unref(ps_mask* mask);

Expand Down
46 changes: 23 additions & 23 deletions src/gfx/gfx_line_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace gfx {

// dda_line_interpolator
template <int FractionShift, int YShift = 0>
template <int32_t FractionShift, int32_t YShift = 0>
class gfx_dda_line_interpolator
{
public:
Expand All @@ -23,9 +23,9 @@ class gfx_dda_line_interpolator
{
}

gfx_dda_line_interpolator(int y1, int y2, unsigned int count)
gfx_dda_line_interpolator(int32_t y1, int32_t y2, uint32_t count)
: m_y(y1)
, m_inc(((y2 - y1) << FractionShift) / (int)count)
, m_inc(((int32_t)((uint32_t)(y2 - y1) << FractionShift)) / (int32_t)count)
, m_dy(0)
{
}
Expand All @@ -40,30 +40,30 @@ class gfx_dda_line_interpolator
m_dy -= m_inc;
}

void operator += (unsigned int n)
void operator += (uint32_t n)
{
m_dy += m_inc * n;
}

void operator -= (unsigned int n)
void operator -= (uint32_t n)
{
m_dy -= m_inc * n;
}

int y(void) const { return m_y + (m_dy >> (FractionShift - YShift)); }
int dy(void) const { return m_dy; }
int32_t y(void) const { return m_y + (m_dy >> (FractionShift - YShift)); }
int32_t dy(void) const { return m_dy; }

private:
int m_y;
int m_inc;
int m_dy;
int32_t m_y;
int32_t m_inc;
int32_t m_dy;
};

// dda2 line interpolator
class gfx_dda2_line_interpolator
{
public:
typedef int save_data_type;
typedef int32_t save_data_type;
enum {
save_size = 2,
};
Expand All @@ -74,7 +74,7 @@ class gfx_dda2_line_interpolator
}

// forward-adjusted line
gfx_dda2_line_interpolator(int y1, int y2, int count)
gfx_dda2_line_interpolator(int32_t y1, int32_t y2, int32_t count)
: m_cnt(count <= 0 ? 1 : count)
, m_lft((y2 - y1) / m_cnt)
, m_rem((y2 - y1) % m_cnt)
Expand All @@ -90,7 +90,7 @@ class gfx_dda2_line_interpolator
}

// backward-adjusted line
gfx_dda2_line_interpolator(int y1, int y2, int count, int)
gfx_dda2_line_interpolator(int32_t y1, int32_t y2, int32_t count, int)
: m_cnt(count <= 0 ? 1 : count)
, m_lft((y2 - y1) / m_cnt)
, m_rem((y2 - y1) % m_cnt)
Expand All @@ -105,7 +105,7 @@ class gfx_dda2_line_interpolator
}

// backward-adjusted line
gfx_dda2_line_interpolator(int y, int count)
gfx_dda2_line_interpolator(int32_t y, int32_t count)
: m_cnt(count <= 0 ? 1 : count)
, m_lft(y / m_cnt)
, m_rem(y % m_cnt)
Expand Down Expand Up @@ -161,16 +161,16 @@ class gfx_dda2_line_interpolator
m_mod += m_cnt;
}

int mod(void) const { return m_mod; }
int rem(void) const { return m_rem; }
int lft(void) const { return m_lft; }
int y(void) const { return m_y; }
int32_t mod(void) const { return m_mod; }
int32_t rem(void) const { return m_rem; }
int32_t lft(void) const { return m_lft; }
int32_t y(void) const { return m_y; }
private:
int m_cnt;
int m_lft;
int m_rem;
int m_mod;
int m_y;
int32_t m_cnt;
int32_t m_lft;
int32_t m_rem;
int32_t m_mod;
int32_t m_y;
};

}
Expand Down
8 changes: 4 additions & 4 deletions src/gfx/gfx_rasterizer_cell.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class gfx_rasterizer_cells_aa
incr = 1;
if (dx == 0) {
int ex = x1 >> poly_subpixel_shift;
int two_fx = (x1 - (ex << poly_subpixel_shift)) << 1;
int two_fx = (int32_t)((uint32_t)(x1 - (int32_t)((uint32_t)ex << poly_subpixel_shift)) << 1);
int area;

first = poly_subpixel_scale;
Expand Down Expand Up @@ -294,7 +294,7 @@ class gfx_rasterizer_cells_aa
set_curr_cell(x_from >> poly_subpixel_shift, ey1);

if (ey1 != ey2) {
p = dx << poly_subpixel_shift;
p = (int32_t)((uint32_t)dx << poly_subpixel_shift);
lift = p / dy;
rem = p % dy;

Expand Down Expand Up @@ -510,7 +510,7 @@ class gfx_rasterizer_cells_aa
y1 += delta;

if (ex1 != ex2) {
p = (y2 - y1 + delta) << poly_subpixel_shift;
p = (int32_t)((uint32_t)(y2 - y1 + delta) << poly_subpixel_shift);
lift = p / dx;
rem = p % dx;

Expand All @@ -530,7 +530,7 @@ class gfx_rasterizer_cells_aa
}

m_curr_cell.cover += delta;
m_curr_cell.area += (delta << poly_subpixel_shift);
m_curr_cell.area += (int32_t)((uint32_t)delta << poly_subpixel_shift);
y1 += delta;
ex1 += incr;
set_curr_cell(ex1, ey);
Expand Down
10 changes: 5 additions & 5 deletions src/gfx/gfx_rasterizer_scanline.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ class gfx_rasterizer_scanline_aa
const cell* cur_cell = *cells;
int x = cur_cell->x;
int area = cur_cell->area;
unsigned int alpha;
uint32_t alpha;

cover += cur_cell->cover;

Expand All @@ -397,15 +397,15 @@ class gfx_rasterizer_scanline_aa
}

if (area) {
alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
alpha = calculate_alpha((int32_t)((uint32_t)cover << (poly_subpixel_shift + 1)) - area);
if (alpha) {
sl.add_cell(x, alpha);
}
x++;
}

if (num_cells && cur_cell->x > x) {
alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
alpha = calculate_alpha((int32_t)((uint32_t)cover << (poly_subpixel_shift + 1)));
if (alpha) {
sl.add_span(x, cur_cell->x - x, alpha);
}
Expand Down Expand Up @@ -459,7 +459,7 @@ class gfx_rasterizer_scanline_aa

if (area) {
if (tx == x) {
alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
alpha = calculate_alpha((int32_t)((uint32_t)cover << (poly_subpixel_shift + 1)) - area);
if (alpha) {
sl.add_cell(x, alpha);
if (sl.hit()) {
Expand All @@ -473,7 +473,7 @@ class gfx_rasterizer_scanline_aa
if (num_cells && cur_cell->x > x) {
int sx = cur_cell->x - x;
if ((tx >= x) && (tx < (x + sx))) {
alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
alpha = calculate_alpha((int32_t)((uint32_t)cover << (poly_subpixel_shift + 1)));
if (alpha) {
sl.add_span(x, sx, alpha);
if (sl.hit()) {
Expand Down
57 changes: 57 additions & 0 deletions src/picasso_canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,61 @@ ps_canvas* PICAPI ps_canvas_create_from_image(ps_image* i, const ps_rect* r)
}
}

ps_canvas* PICAPI ps_canvas_create_from_mask(ps_mask* m, const ps_rect* r)
{
if (!picasso::is_valid_system_device()) {
global_status = STATUS_DEVICE_ERROR;
return NULL;
}

if (!m) {
global_status = STATUS_INVALID_ARGUMENT;
return NULL;
}

ps_rect rc = {0, 0, (float)m->mask.width(), (float)m->mask.height()};
if (r) {
if (r->x > 0) {
rc.x = r->x;
}
if (r->y > 0) {
rc.y = r->y;
}
if (r->w > 0) {
rc.w = r->w;
}
if (r->h > 0) {
rc.h = r->h;
}
}

picasso::painter* pa = picasso::get_painter_from_format(COLOR_FORMAT_A8);
if (!pa) {
return NULL;
}

ps_canvas* p = (ps_canvas*)mem_malloc(sizeof(ps_canvas));
if (p) {
p->refcount = 1;
p->fmt = COLOR_FORMAT_A8;
p->p = pa;
p->flage = buffer_alloc_mask;
p->host = (void*)ps_mask_ref(m);
p->mask = NULL;
int bpp = picasso::_bytes_per_color(p->fmt);
new ((void*) & (p->buffer)) picasso::rendering_buffer;
p->buffer.attach(m->mask.buffer() + _iround(rc.y * m->mask.stride() + rc.x * bpp),
_iround(rc.w), _iround(rc.h), m->mask.stride());
p->p->attach(p->buffer);
global_status = STATUS_SUCCEED;
return p;
} else {
delete pa; //mem_free painter on error
global_status = STATUS_OUT_OF_MEMORY;
return NULL;
}
}

ps_canvas* PICAPI ps_canvas_create_with_data(ps_byte* addr, ps_color_format fmt, int w, int h, int pitch)
{
if (!picasso::is_valid_system_device()) {
Expand Down Expand Up @@ -448,6 +503,8 @@ void PICAPI ps_canvas_unref(ps_canvas* canvas)
ps_image_unref(static_cast<ps_image*>(canvas->host));
} else if (canvas->flage == buffer_alloc_canvas) {
ps_canvas_unref(static_cast<ps_canvas*>(canvas->host));
} else if (canvas->flage == buffer_alloc_mask) {
ps_mask_unref(static_cast<ps_mask*>(canvas->host));
}

if (canvas->mask) {
Expand Down
Loading

0 comments on commit 585d4f5

Please sign in to comment.