123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840 |
- #include <rtgui/rtgui.h>
- #include <rtgui/rtgui_system.h>
- #include <rtgui/dc.h>
- #include <rtgui/dc_trans.h>
- struct rtgui_dc_trans
- {
- struct rtgui_matrix m;
- struct rtgui_dc *owner;
- int use_aa;
- };
- struct rtgui_dc_trans* rtgui_dc_trans_create(struct rtgui_dc *owner)
- {
- struct rtgui_dc_trans *dct;
- dct = (struct rtgui_dc_trans*)rtgui_malloc(sizeof(*dct));
- if (!dct)
- return RT_NULL;
- rtgu_matrix_identity(&dct->m);
- dct->owner = owner;
- dct->use_aa = 0;
- return dct;
- }
- RTM_EXPORT(rtgui_dc_trans_create);
- void rtgui_dc_trans_destroy(struct rtgui_dc_trans *dct)
- {
- rtgui_free(dct);
- }
- RTM_EXPORT(rtgui_dc_trans_destroy);
- void rtgui_dc_trans_set_aa(struct rtgui_dc_trans *dct, int use_aa)
- {
- RT_ASSERT(dct);
- dct->use_aa = use_aa;
- }
- RTM_EXPORT(rtgui_dc_trans_set_aa);
- void rtgui_dc_trans_rotate(struct rtgui_dc_trans *dct, double degree)
- {
- RT_ASSERT(dct);
- rtgui_matrix_rotate(&dct->m, degree * RTGUI_MATRIX_FRAC / 360.0);
- }
- RTM_EXPORT(rtgui_dc_trans_rotate);
- void rtgui_dc_trans_scale(struct rtgui_dc_trans *dct,
- double sx,
- double sy)
- {
- RT_ASSERT(dct);
- rtgui_matrix_scale(&dct->m, sx * RTGUI_MATRIX_FRAC, sy * RTGUI_MATRIX_FRAC);
- }
- RTM_EXPORT(rtgui_dc_trans_scale);
- void rtgui_dc_trans_move(struct rtgui_dc_trans *dct,
- int dx,
- int dy)
- {
- RT_ASSERT(dct);
- rtgui_matrix_move(&dct->m, dx, dy);
- }
- RTM_EXPORT(rtgui_dc_trans_move);
- void rtgui_dc_trans_get_new_wh(struct rtgui_dc_trans *dct,
- int *new_wp,
- int *new_hp)
- {
- struct rtgui_rect rect;
- struct rtgui_point topleft, topright, bottomright;
- RT_ASSERT(dct);
- if (!new_wp && !new_hp)
- return;
- rtgui_dc_get_rect(dct->owner, &rect);
- /* We ignore the movement components in the matrix. */
- /* Transform result of (0, h). */
- rtgui_matrix_mul_point_nomove(&topleft, 0, rect.y2,
- &dct->m);
- /* Transform result of (w, h). */
- rtgui_matrix_mul_point_nomove(&topright, rect.x2, rect.y2,
- &dct->m);
- /* Transform result of (w, 0). */
- rtgui_matrix_mul_point_nomove(&bottomright,
- rect.x2, 0, &dct->m);
- /* Transform result of (0, 0) is always (0, 0). */
- #define NORMALIZE(x) do { if (x < 0) x = 0; } while (0)
- if (new_wp)
- {
- int neww;
- /* Ignore the nagtive parts. */
- NORMALIZE(topright.x);
- NORMALIZE(topleft.x);
- NORMALIZE(bottomright.x);
- neww = _UI_MAX(topright.x, _UI_ABS(topleft.x - bottomright.x))
- + dct->m.m[4];
- NORMALIZE(neww);
- *new_wp = neww;
- }
- if (new_hp)
- {
- int newh;
- NORMALIZE(topright.y);
- NORMALIZE(topleft.y);
- NORMALIZE(bottomright.y);
- newh = _UI_MAX(topright.y, _UI_ABS(topleft.y - bottomright.y))
- + dct->m.m[5];
- NORMALIZE(newh);
- *new_hp = newh;
- }
- #undef NORMALIZE
- }
- RTM_EXPORT(rtgui_dc_trans_get_new_wh);
- struct _fb_rect
- {
- void *fb;
- /* unit: pixel */
- rt_uint16_t width, height;
- /* unit: pixel */
- rt_uint16_t skip;
- };
- /* FrameRect to FrameRect, same format, 2 Bytes/pixel. */
- static void _blit_rotate_FR2FR_SF2B(struct _fb_rect* RTGUI_RESTRICT src,
- const struct rtgui_point *dc_point,
- struct _fb_rect* RTGUI_RESTRICT dst,
- const struct rtgui_matrix *invm)
- {
- rt_uint16_t* RTGUI_RESTRICT srcp = (rt_uint16_t*)src->fb;
- rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->fb;
- int neww = dst->width;
- int newh = dst->height;
- int oriw = src->width;
- int orih = src->height;
- int nx, ny;
- int dx, dy;
- /* Delta of bx/by when nx++. */
- dx = invm->m[0];
- dy = invm->m[1];
- for (ny = dc_point->y; ny < newh; ny++)
- {
- /* Base x, y. */
- int bx, by;
- bx = dc_point->x * dx + ny * invm->m[2] + RTGUI_MATRIX_FRAC * invm->m[4];
- by = dc_point->x * dy + ny * invm->m[3] + RTGUI_MATRIX_FRAC * invm->m[5];
- for (nx = dc_point->x; nx < neww; nx++, dstp++)
- {
- /* The coordinate in the source frame. */
- int rx, ry;
- bx += dx;
- by += dy;
- if (bx < 0 || by < 0)
- continue;
- rx = bx / RTGUI_MATRIX_FRAC;
- ry = by / RTGUI_MATRIX_FRAC;
- if (oriw <= rx || orih <= ry)
- continue;
- /* We take the source as a whole and ignore the src->skip. */
- *dstp = srcp[ry * oriw + rx];
- }
- dstp += dst->skip - neww;
- }
- }
- /* FrameRect to FrameRect, same format, 2 Bytes/pixel, with AA. */
- static void _blit_rotate_FR2FR_SF2B_AA(struct _fb_rect* RTGUI_RESTRICT src,
- const struct rtgui_point *dc_point,
- struct _fb_rect* RTGUI_RESTRICT dst,
- const struct rtgui_matrix *invm)
- {
- rt_uint16_t* RTGUI_RESTRICT srcp = (rt_uint16_t*)src->fb;
- rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->fb;
- int neww = dst->width;
- int newh = dst->height;
- int oriw = src->width;
- int orih = src->height;
- int nx, ny;
- int dx, dy;
- dx = invm->m[0];
- dy = invm->m[1];
- for (ny = dc_point->y; ny < newh; ny++)
- {
- /* Base x, y. */
- int bx, by;
- bx = dc_point->x * dx + ny * invm->m[2] + RTGUI_MATRIX_FRAC * invm->m[4];
- by = dc_point->x * dy + ny * invm->m[3] + RTGUI_MATRIX_FRAC * invm->m[5];
- for (nx = dc_point->x; nx < neww; nx++, dstp++)
- {
- /* Color of pixels:
- * c00 c01
- * c10 c11 */
- rt_uint32_t c00, c01, c10, c11;
- int rx, ry, sx, sy;
- bx += dx;
- by += dy;
- if (bx < 0 || by < 0)
- continue;
- rx = bx / RTGUI_MATRIX_FRAC;
- ry = by / RTGUI_MATRIX_FRAC;
- if (oriw - 1 <= rx || orih - 1 <= ry)
- continue;
- c00 = srcp[ry * oriw + rx];
- c01 = srcp[ry * oriw + rx + 1];
- c10 = srcp[(ry + 1) * oriw + rx];
- c11 = srcp[(ry + 1) * oriw + rx + 1];
- c00 = (c00 | c00 << 16) & 0x07e0f81f;
- c01 = (c01 | c01 << 16) & 0x07e0f81f;
- c10 = (c10 | c10 << 16) & 0x07e0f81f;
- c11 = (c11 | c11 << 16) & 0x07e0f81f;
- /* We down scale the interpolate factor to 5 bits to avoid color
- * corruption. */
- sx = ((unsigned int)bx % RTGUI_MATRIX_FRAC) >> (RTGUI_MATRIX_FRAC_BITS - 5);
- sy = ((unsigned int)by % RTGUI_MATRIX_FRAC) >> (RTGUI_MATRIX_FRAC_BITS - 5);
- if (sx)
- c00 = ((c01 - c00) * sx / 32 + c00) & 0x07e0f81f;
- if (sx && sy)
- c10 = ((c11 - c10) * sx / 32 + c10) & 0x07e0f81f;
- if (sy)
- c00 = ((c10 - c00) * sy / 32 + c00) & 0x07e0f81f;
- /* We take the source as a whole and ignore the src->skip. */
- *dstp = c00 | (c00 >> 16);
- }
- dstp += dst->skip - neww;
- }
- }
- union _rgba
- {
- rt_uint32_t blk;
- struct
- {
- rt_uint8_t r, g, b, a;
- } d;
- };
- /* FrameRect to FrameRect, same format, 4 Bytes/pixel. */
- static void _blit_rotate_FR2FR_SF4B(struct _fb_rect* RTGUI_RESTRICT src,
- const struct rtgui_point *dc_point,
- struct _fb_rect* RTGUI_RESTRICT dst,
- const struct rtgui_matrix *invm)
- {
- rt_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb;
- rt_uint32_t* RTGUI_RESTRICT dstp = (rt_uint32_t*)dst->fb;
- int neww = dst->width;
- int newh = dst->height;
- int oriw = src->width;
- int orih = src->height;
- int nx, ny;
- int dx, dy;
- dx = invm->m[0];
- dy = invm->m[1];
- for (ny = dc_point->y; ny < newh; ny++)
- {
- /* Base x, y. */
- int bx, by;
- bx = dc_point->x * dx + ny * invm->m[2] + RTGUI_MATRIX_FRAC * invm->m[4];
- by = dc_point->x * dy + ny * invm->m[3] + RTGUI_MATRIX_FRAC * invm->m[5];
- for (nx = dc_point->x; nx < neww; nx++, dstp++)
- {
- union _rgba spix, dpix;
- int rx, ry, a;
- bx += dx;
- by += dy;
- if (bx < 0 || by < 0)
- continue;
- rx = bx / RTGUI_MATRIX_FRAC;
- ry = by / RTGUI_MATRIX_FRAC;
- if (oriw <= rx || orih <= ry)
- continue;
- spix.blk = srcp[ry * oriw + rx];
- /* Down scale the alpha to 5 bits. */
- a = spix.d.a >> 3;
- if (a == 0)
- continue;
- if (a == 31)
- {
- *dstp = spix.blk;
- continue;
- }
- dpix.blk = *dstp;
- dpix.d.r = (spix.d.r - dpix.d.r) * a / 32 + dpix.d.r;
- dpix.d.g = (spix.d.g - dpix.d.g) * a / 32 + dpix.d.g;
- dpix.d.b = (spix.d.b - dpix.d.b) * a / 32 + dpix.d.b;
- *dstp = dpix.blk;
- }
- dstp += dst->skip - neww;
- }
- }
- /* FrameRect to FrameRect, same format, 4 Bytes/pixel, with AA. */
- static void _blit_rotate_FR2FR_SF4B_AA(struct _fb_rect* RTGUI_RESTRICT src,
- const struct rtgui_point *dc_point,
- struct _fb_rect* RTGUI_RESTRICT dst,
- const struct rtgui_matrix *invm)
- {
- rt_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb;
- rt_uint32_t* RTGUI_RESTRICT dstp = (rt_uint32_t*)dst->fb;
- int neww = dst->width;
- int newh = dst->height;
- int oriw = src->width;
- int orih = src->height;
- int nx, ny;
- int dx, dy;
- dx = invm->m[0];
- dy = invm->m[1];
- for (ny = dc_point->y; ny < newh; ny++)
- {
- /* Base x, y. */
- int bx, by;
- bx = dc_point->x * dx + ny * invm->m[2] + RTGUI_MATRIX_FRAC * invm->m[4];
- by = dc_point->x * dy + ny * invm->m[3] + RTGUI_MATRIX_FRAC * invm->m[5];
- for (nx = dc_point->x; nx < neww; nx++, dstp++)
- {
- union _rgba spix00, spix01, spix10, spix11, dpix;
- int rx, ry, a, sx, sy;
- bx += dx;
- by += dy;
- if (bx < 0 || by < 0)
- continue;
- rx = bx / RTGUI_MATRIX_FRAC;
- ry = by / RTGUI_MATRIX_FRAC;
- if (oriw - 1 <= rx || orih - 1 <= ry)
- continue;
- spix00.blk = srcp[ry * oriw + rx];
- /* Down scale the interpolate factor to 5 bits. */
- sx = ((unsigned int)bx % RTGUI_MATRIX_FRAC) >> (RTGUI_MATRIX_FRAC_BITS - 5);
- sy = ((unsigned int)by % RTGUI_MATRIX_FRAC) >> (RTGUI_MATRIX_FRAC_BITS - 5);
- spix01.blk = srcp[ry * oriw + rx + 1];
- spix10.blk = srcp[(ry + 1) * oriw + rx];
- spix11.blk = srcp[(ry + 1) * oriw + rx + 1];
- if (sx)
- spix00.d.a = (spix01.d.a - spix00.d.a) * sx / 32 + spix00.d.a;
- if (sx && sy)
- spix10.d.a = (spix11.d.a - spix10.d.a) * sx / 32 + spix10.d.a;
- if (sy)
- spix00.d.a = (spix10.d.a - spix00.d.a) * sy / 32 + spix00.d.a;
- a = spix00.d.a >> 3;
- if (a == 0)
- continue;
- if (sx)
- {
- spix00.d.r = (spix01.d.r - spix00.d.r) * sx / 32 + spix00.d.r;
- spix00.d.g = (spix01.d.g - spix00.d.g) * sx / 32 + spix00.d.g;
- spix00.d.b = (spix01.d.b - spix00.d.b) * sx / 32 + spix00.d.b;
- }
- if (sx && sy)
- {
- spix10.d.r = (spix11.d.r - spix10.d.r) * sx / 32 + spix10.d.r;
- spix10.d.g = (spix11.d.g - spix10.d.g) * sx / 32 + spix10.d.g;
- spix10.d.b = (spix11.d.b - spix10.d.b) * sx / 32 + spix10.d.b;
- }
- if (sy)
- {
- spix00.d.r = (spix10.d.r - spix00.d.r) * sy / 32 + spix00.d.r;
- spix00.d.g = (spix10.d.g - spix00.d.g) * sy / 32 + spix00.d.g;
- spix00.d.b = (spix10.d.b - spix00.d.b) * sy / 32 + spix00.d.b;
- }
- if (a == (255 >> 3))
- {
- *dstp = spix00.blk;
- continue;
- }
- dpix.blk = *dstp;
- dpix.d.r = (spix00.d.r - dpix.d.r) * a / 32 + dpix.d.r;
- dpix.d.g = (spix00.d.g - dpix.d.g) * a / 32 + dpix.d.g;
- dpix.d.b = (spix00.d.b - dpix.d.b) * a / 32 + dpix.d.b;
- *dstp = dpix.blk;
- }
- dstp += dst->skip - neww;
- }
- }
- /* FrameRect to FrameRect, from ARGB8888 to RGB565. */
- static void _blit_rotate_FR2FR_ARGB2RGB565(struct _fb_rect* RTGUI_RESTRICT src,
- const struct rtgui_point *dc_point,
- struct _fb_rect* RTGUI_RESTRICT dst,
- const struct rtgui_matrix *invm)
- {
- rt_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb;
- rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->fb;
- int neww = dst->width;
- int newh = dst->height;
- int oriw = src->width;
- int orih = src->height;
- int nx, ny;
- int dx, dy;
- dx = invm->m[0];
- dy = invm->m[1];
- for (ny = dc_point->y; ny < newh; ny++)
- {
- /* Base x, y. */
- int bx, by;
- bx = dc_point->x * dx + ny * invm->m[2] + RTGUI_MATRIX_FRAC * invm->m[4];
- by = dc_point->x * dy + ny * invm->m[3] + RTGUI_MATRIX_FRAC * invm->m[5];
- for (nx = dc_point->x; nx < neww; nx++, dstp++)
- {
- int rx, ry;
- int alpha;
- rt_uint32_t op;
- bx += dx;
- by += dy;
- if (bx < 0 || by < 0)
- continue;
- rx = bx / RTGUI_MATRIX_FRAC;
- ry = by / RTGUI_MATRIX_FRAC;
- if (oriw <= rx || orih <= ry)
- continue;
- /* We take the source as a whole and ignore the src->skip. */
- op = srcp[ry * oriw + rx];
- /* downscale alpha to 5 bits */
- alpha = op >> 27;
- if (alpha == (255 >> 3))
- {
- *dstp = (rt_uint16_t)((op >> 8 & 0xf800) +
- (op >> 5 & 0x7e0) +
- (op >> 3 & 0x1f));
- }
- else if (alpha != 0)
- {
- /* We take the source as a whole and ignore the src->skip. */
- rt_uint32_t d = *dstp;
- /*
- * convert source and destination to G0RAB65565
- * and blend all components at the same time
- */
- op = ((op & 0xfc00) << 11) + (op >> 8 & 0xf800)
- + (op >> 3 & 0x1f);
- d = (d | d << 16) & 0x07e0f81f;
- d += (op - d) * alpha >> 5;
- d &= 0x07e0f81f;
- *dstp = (rt_uint16_t)(d | d >> 16);
- }
- }
- dstp += dst->skip - neww;
- }
- }
- /* FrameRect to FrameRect, from ARGB8888 to RGB565. */
- static void _blit_rotate_FR2FR_ARGB2RGB565_AA(struct _fb_rect* RTGUI_RESTRICT src,
- const struct rtgui_point *dc_point,
- struct _fb_rect* RTGUI_RESTRICT dst,
- const struct rtgui_matrix *invm)
- {
- rt_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb;
- rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->fb;
- int neww = dst->width;
- int newh = dst->height;
- int oriw = src->width;
- int orih = src->height;
- int nx, ny;
- int dx, dy;
- dx = invm->m[0];
- dy = invm->m[1];
- for (ny = dc_point->y; ny < newh; ny++)
- {
- /* Base x, y. */
- int bx, by;
- bx = dc_point->x * dx + ny * invm->m[2] + RTGUI_MATRIX_FRAC * invm->m[4];
- by = dc_point->x * dy + ny * invm->m[3] + RTGUI_MATRIX_FRAC * invm->m[5];
- for (nx = dc_point->x; nx < neww; nx++, dstp++)
- {
- rt_uint32_t op00, op01, op10, op11;
- rt_uint8_t a00, a01, a10, a11;
- int rx, ry, sx, sy;
- bx += dx;
- by += dy;
- if (bx < 0 || by < 0)
- continue;
- rx = bx / RTGUI_MATRIX_FRAC;
- ry = by / RTGUI_MATRIX_FRAC;
- if (oriw - 1 <= rx || orih - 1 <= ry)
- continue;
- op00 = srcp[ry * oriw + rx];
- op01 = srcp[ry * oriw + rx + 1];
- op10 = srcp[(ry + 1) * oriw + rx];
- op11 = srcp[(ry + 1) * oriw + rx + 1];
- /* Down scale the interpolate factor to 5 bits. */
- sx = ((unsigned int)bx % RTGUI_MATRIX_FRAC) >> (RTGUI_MATRIX_FRAC_BITS - 5);
- sy = ((unsigned int)by % RTGUI_MATRIX_FRAC) >> (RTGUI_MATRIX_FRAC_BITS - 5);
- a00 = op00 >> 27;
- a01 = op01 >> 27;
- a11 = op11 >> 27;
- a10 = op10 >> 27;
- if (sx)
- a00 = (a01 - a00) * sx / 32 + a00;
- if (sx && sy)
- a10 = (a11 - a10) * sx / 32 + a10;
- if (sy)
- a00 = (a10 - a00) * sy / 32 + a00;
- if (a00 == 0)
- continue;
- op00 = (((op00 >> 10) & 0x3f) << 21) | (((op00 >> 19) & 0x1f) << 11) | (op00 >> 3 & 0x1f);
- op10 = (((op10 >> 10) & 0x3f) << 21) | (((op10 >> 19) & 0x1f) << 11) | (op10 >> 3 & 0x1f);
- op01 = (((op01 >> 10) & 0x3f) << 21) | (((op01 >> 19) & 0x1f) << 11) | (op01 >> 3 & 0x1f);
- op11 = (((op11 >> 10) & 0x3f) << 21) | (((op11 >> 19) & 0x1f) << 11) | (op11 >> 3 & 0x1f);
- if (sx)
- {
- op00 = ((op01 - op00) * sx / 32 + op00) & 0x07e0f81f;
- }
- if (sx && sy)
- {
- op10 = ((op11 - op10) * sx / 32 + op10) & 0x07e0f81f;
- }
- if (sy)
- {
- op00 = ((op10 - op00) * sy / 32 + op00) & 0x07e0f81f;
- }
- if (a00 == (255 >> 3))
- {
- *dstp = op00 | (op00 >> 16);
- }
- else if (a00 != 0)
- {
- rt_uint32_t d = *dstp;
- d = (d | d << 16) & 0x07e0f81f;
- d += (op00 - d) * a00 >> 5;
- d &= 0x07e0f81f;
- *dstp = (rt_uint16_t)(d | d >> 16);
- }
- }
- dstp += dst->skip - neww;
- }
- }
- static void _blit_rotate_B2B(struct rtgui_dc_trans *dct,
- const struct rtgui_point *dc_point,
- struct rtgui_dc_buffer* RTGUI_RESTRICT dest,
- struct rtgui_rect *rect,
- const struct rtgui_matrix *invm,
- int neww, int newh)
- {
- struct rtgui_rect srcrect;
- struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer*)dct->owner;
- struct _fb_rect srcfb, dstfb;
- rtgui_dc_get_rect(dct->owner, &srcrect);
- srcfb.fb = ((struct rtgui_dc_buffer*)dct->owner)->pixel;
- srcfb.width = srcrect.x2;
- srcfb.height = srcrect.y2;
- srcfb.skip = 0;
- dstfb.fb = dest->pixel + rtgui_color_get_bpp(dest->pixel_format) * (rect->x1 + rect->y1 * dest->width);
- dstfb.width = neww;
- dstfb.height = newh;
- dstfb.skip = dest->width;
- if (dc->pixel_format == dest->pixel_format)
- {
- switch (rtgui_color_get_bpp(dest->pixel_format)) {
- case 2:
- if (dct->use_aa)
- _blit_rotate_FR2FR_SF2B_AA(&srcfb, dc_point,
- &dstfb, invm);
- else
- _blit_rotate_FR2FR_SF2B(&srcfb, dc_point,
- &dstfb, invm);
- break;
- case 4:
- if (dct->use_aa)
- _blit_rotate_FR2FR_SF4B_AA(&srcfb, dc_point,
- &dstfb, invm);
- else
- _blit_rotate_FR2FR_SF4B(&srcfb, dc_point,
- &dstfb, invm);
- break;
- default:
- rt_kprintf("could not handle bpp: %d\n",
- rtgui_color_get_bpp(dest->pixel_format));
- return;
- }
- }
- else if (dc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888 &&
- dest->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
- {
- if (dct->use_aa)
- _blit_rotate_FR2FR_ARGB2RGB565_AA(&srcfb, dc_point,
- &dstfb, invm);
- else
- _blit_rotate_FR2FR_ARGB2RGB565(&srcfb, dc_point,
- &dstfb, invm);
- }
- else
- {
- rt_kprintf("not implemented yet\n");
- return;
- }
- }
- static void _blit_rotate_B2H(struct rtgui_dc_trans *dct,
- const struct rtgui_point *dc_point,
- struct rtgui_dc_hw* dest,
- struct rtgui_rect *rect,
- const struct rtgui_matrix *invm,
- int neww, int newh)
- {
- struct rtgui_rect srcrect;
- int start_pix;
- struct _fb_rect srcfb, dstfb;
- struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer*)dct->owner;
- if (dest->hw_driver->framebuffer == RT_NULL)
- {
- rt_kprintf("Only support framebuffer hw dc\n");
- return;
- }
- rtgui_dc_get_rect(dct->owner, &srcrect);
- srcfb.fb = ((struct rtgui_dc_buffer*)dct->owner)->pixel;
- srcfb.width = srcrect.x2;
- srcfb.height = srcrect.y2;
- srcfb.skip = 0;
- /* Start point of the widget. */
- start_pix = dest->owner->extent.x1 + dest->owner->extent.y1 * dest->hw_driver->width;
- /* Start point of the inner rect. */
- start_pix += rect->x1 + rect->y1 * dest->hw_driver->width;
- dstfb.fb = (void*)(dest->hw_driver->framebuffer
- + rtgui_color_get_bpp(dest->hw_driver->pixel_format) * start_pix);
- dstfb.width = neww;
- dstfb.height = newh;
- dstfb.skip = dest->hw_driver->width;
- if (dc->pixel_format == dest->hw_driver->pixel_format)
- {
- switch (rtgui_color_get_bpp(dest->hw_driver->pixel_format)) {
- case 2:
- if (dct->use_aa)
- _blit_rotate_FR2FR_SF2B_AA(&srcfb, dc_point,
- &dstfb, invm);
- else
- _blit_rotate_FR2FR_SF2B(&srcfb, dc_point,
- &dstfb, invm);
- break;
- case 4:
- if (dct->use_aa)
- _blit_rotate_FR2FR_SF4B_AA(&srcfb, dc_point,
- &dstfb, invm);
- else
- _blit_rotate_FR2FR_SF4B(&srcfb, dc_point,
- &dstfb, invm);
- break;
- default:
- rt_kprintf("could not handle bpp: %d\n",
- rtgui_color_get_bpp(dest->hw_driver->pixel_format));
- return;
- }
- }
- else if (dc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888 &&
- dest->hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
- {
- if (dct->use_aa)
- _blit_rotate_FR2FR_ARGB2RGB565_AA(&srcfb, dc_point,
- &dstfb, invm);
- else
- _blit_rotate_FR2FR_ARGB2RGB565(&srcfb, dc_point,
- &dstfb, invm);
- }
- else
- {
- rt_kprintf("not implemented yet\n");
- return;
- }
- }
- void rtgui_dc_trans_blit(struct rtgui_dc_trans *dct,
- struct rtgui_point *dc_point,
- struct rtgui_dc *dest,
- struct rtgui_rect *rect)
- {
- struct rtgui_rect bkrect;
- struct rtgui_matrix invm;
- struct rtgui_point dp;
- int neww, newh;
- RT_ASSERT(dct);
- RT_ASSERT(dest);
- if (dc_point == RT_NULL)
- {
- dp.x = dp.y = 0;
- dc_point = &dp;
- }
- if (rect == RT_NULL)
- {
- rtgui_dc_get_rect(dest, &bkrect);
- rect = &bkrect;
- }
- rtgui_dc_trans_get_new_wh(dct, &neww, &newh);
- if (dc_point->x < 0)
- {
- neww -= dc_point->x;
- if (neww < 0)
- return;
- dc_point->x = 0;
- }
- else if (dc_point->x > neww)
- return;
- if (dc_point->y < 0)
- {
- newh -= dc_point->y;
- if (newh < 0)
- return;
- dc_point->y = 0;
- }
- else if (dc_point->y > newh)
- return;
- if (rtgui_matrix_inverse(&dct->m, &invm))
- return;
- if (rtgui_rect_width(*rect) < neww - dc_point->x)
- neww = dc_point->x + rtgui_rect_width(*rect);
- if (rtgui_rect_height(*rect) < newh - dc_point->y)
- newh = dc_point->y + rtgui_rect_height(*rect);
- /* Route to different optimized routines. */
- if (dct->owner->type == RTGUI_DC_BUFFER)
- {
- if (dest->type == RTGUI_DC_BUFFER)
- _blit_rotate_B2B(dct, dc_point,
- (struct rtgui_dc_buffer*)dest,
- rect, &invm, neww, newh);
- else if (dest->type == RTGUI_DC_HW)
- _blit_rotate_B2H(dct, dc_point,
- (struct rtgui_dc_hw*)dest,
- rect, &invm, neww, newh);
- else if (dest->type == RTGUI_DC_CLIENT)
- // TODO:
- ;
- else
- rt_kprintf("unknown dc for dc_trans\n");
- }
- else
- rt_kprintf("not implemented yet\n");
- }
- RTM_EXPORT(rtgui_dc_trans_blit);
|