dc_trans.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. #include <rtgui/rtgui.h>
  2. #include <rtgui/rtgui_system.h>
  3. #include <rtgui/dc.h>
  4. #include <rtgui/dc_trans.h>
  5. struct rtgui_dc_trans
  6. {
  7. struct rtgui_matrix m;
  8. struct rtgui_dc *owner;
  9. int use_aa;
  10. };
  11. struct rtgui_dc_trans* rtgui_dc_trans_create(struct rtgui_dc *owner)
  12. {
  13. struct rtgui_dc_trans *dct;
  14. dct = (struct rtgui_dc_trans*)rtgui_malloc(sizeof(*dct));
  15. if (!dct)
  16. return RT_NULL;
  17. rtgu_matrix_identity(&dct->m);
  18. dct->owner = owner;
  19. dct->use_aa = 0;
  20. return dct;
  21. }
  22. RTM_EXPORT(rtgui_dc_trans_create);
  23. void rtgui_dc_trans_destroy(struct rtgui_dc_trans *dct)
  24. {
  25. rtgui_free(dct);
  26. }
  27. RTM_EXPORT(rtgui_dc_trans_destroy);
  28. void rtgui_dc_trans_set_aa(struct rtgui_dc_trans *dct, int use_aa)
  29. {
  30. RT_ASSERT(dct);
  31. dct->use_aa = use_aa;
  32. }
  33. RTM_EXPORT(rtgui_dc_trans_set_aa);
  34. void rtgui_dc_trans_rotate(struct rtgui_dc_trans *dct, double degree)
  35. {
  36. RT_ASSERT(dct);
  37. rtgui_matrix_rotate(&dct->m, degree * RTGUI_MATRIX_FRAC / 360.0);
  38. }
  39. RTM_EXPORT(rtgui_dc_trans_rotate);
  40. void rtgui_dc_trans_scale(struct rtgui_dc_trans *dct,
  41. double sx,
  42. double sy)
  43. {
  44. RT_ASSERT(dct);
  45. rtgui_matrix_scale(&dct->m, sx * RTGUI_MATRIX_FRAC, sy * RTGUI_MATRIX_FRAC);
  46. }
  47. RTM_EXPORT(rtgui_dc_trans_scale);
  48. void rtgui_dc_trans_move(struct rtgui_dc_trans *dct,
  49. int dx,
  50. int dy)
  51. {
  52. RT_ASSERT(dct);
  53. rtgui_matrix_move(&dct->m, dx, dy);
  54. }
  55. RTM_EXPORT(rtgui_dc_trans_move);
  56. void rtgui_dc_trans_get_new_wh(struct rtgui_dc_trans *dct,
  57. int *new_wp,
  58. int *new_hp)
  59. {
  60. struct rtgui_rect rect;
  61. struct rtgui_point topleft, topright, bottomright;
  62. RT_ASSERT(dct);
  63. if (!new_wp && !new_hp)
  64. return;
  65. rtgui_dc_get_rect(dct->owner, &rect);
  66. /* We ignore the movement components in the matrix. */
  67. /* Transform result of (0, h). */
  68. rtgui_matrix_mul_point_nomove(&topleft, 0, rect.y2,
  69. &dct->m);
  70. /* Transform result of (w, h). */
  71. rtgui_matrix_mul_point_nomove(&topright, rect.x2, rect.y2,
  72. &dct->m);
  73. /* Transform result of (w, 0). */
  74. rtgui_matrix_mul_point_nomove(&bottomright,
  75. rect.x2, 0, &dct->m);
  76. /* Transform result of (0, 0) is always (0, 0). */
  77. #define NORMALIZE(x) do { if (x < 0) x = 0; } while (0)
  78. if (new_wp)
  79. {
  80. int neww;
  81. /* Ignore the nagtive parts. */
  82. NORMALIZE(topright.x);
  83. NORMALIZE(topleft.x);
  84. NORMALIZE(bottomright.x);
  85. neww = _UI_MAX(topright.x, _UI_ABS(topleft.x - bottomright.x))
  86. + dct->m.m[4];
  87. NORMALIZE(neww);
  88. *new_wp = neww;
  89. }
  90. if (new_hp)
  91. {
  92. int newh;
  93. NORMALIZE(topright.y);
  94. NORMALIZE(topleft.y);
  95. NORMALIZE(bottomright.y);
  96. newh = _UI_MAX(topright.y, _UI_ABS(topleft.y - bottomright.y))
  97. + dct->m.m[5];
  98. NORMALIZE(newh);
  99. *new_hp = newh;
  100. }
  101. #undef NORMALIZE
  102. }
  103. RTM_EXPORT(rtgui_dc_trans_get_new_wh);
  104. struct _fb_rect
  105. {
  106. void *fb;
  107. /* unit: pixel */
  108. rt_uint16_t width, height;
  109. /* unit: pixel */
  110. rt_uint16_t skip;
  111. };
  112. /* FrameRect to FrameRect, same format, 2 Bytes/pixel. */
  113. static void _blit_rotate_FR2FR_SF2B(struct _fb_rect* RTGUI_RESTRICT src,
  114. const struct rtgui_point *dc_point,
  115. struct _fb_rect* RTGUI_RESTRICT dst,
  116. const struct rtgui_matrix *invm)
  117. {
  118. rt_uint16_t* RTGUI_RESTRICT srcp = (rt_uint16_t*)src->fb;
  119. rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->fb;
  120. int neww = dst->width;
  121. int newh = dst->height;
  122. int oriw = src->width;
  123. int orih = src->height;
  124. int nx, ny;
  125. int dx, dy;
  126. /* Delta of bx/by when nx++. */
  127. dx = invm->m[0];
  128. dy = invm->m[1];
  129. for (ny = dc_point->y; ny < newh; ny++)
  130. {
  131. /* Base x, y. */
  132. int bx, by;
  133. bx = dc_point->x * dx + ny * invm->m[2] + RTGUI_MATRIX_FRAC * invm->m[4];
  134. by = dc_point->x * dy + ny * invm->m[3] + RTGUI_MATRIX_FRAC * invm->m[5];
  135. for (nx = dc_point->x; nx < neww; nx++, dstp++)
  136. {
  137. /* The coordinate in the source frame. */
  138. int rx, ry;
  139. bx += dx;
  140. by += dy;
  141. if (bx < 0 || by < 0)
  142. continue;
  143. rx = bx / RTGUI_MATRIX_FRAC;
  144. ry = by / RTGUI_MATRIX_FRAC;
  145. if (oriw <= rx || orih <= ry)
  146. continue;
  147. /* We take the source as a whole and ignore the src->skip. */
  148. *dstp = srcp[ry * oriw + rx];
  149. }
  150. dstp += dst->skip - neww;
  151. }
  152. }
  153. /* FrameRect to FrameRect, same format, 2 Bytes/pixel, with AA. */
  154. static void _blit_rotate_FR2FR_SF2B_AA(struct _fb_rect* RTGUI_RESTRICT src,
  155. const struct rtgui_point *dc_point,
  156. struct _fb_rect* RTGUI_RESTRICT dst,
  157. const struct rtgui_matrix *invm)
  158. {
  159. rt_uint16_t* RTGUI_RESTRICT srcp = (rt_uint16_t*)src->fb;
  160. rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->fb;
  161. int neww = dst->width;
  162. int newh = dst->height;
  163. int oriw = src->width;
  164. int orih = src->height;
  165. int nx, ny;
  166. int dx, dy;
  167. dx = invm->m[0];
  168. dy = invm->m[1];
  169. for (ny = dc_point->y; ny < newh; ny++)
  170. {
  171. /* Base x, y. */
  172. int bx, by;
  173. bx = dc_point->x * dx + ny * invm->m[2] + RTGUI_MATRIX_FRAC * invm->m[4];
  174. by = dc_point->x * dy + ny * invm->m[3] + RTGUI_MATRIX_FRAC * invm->m[5];
  175. for (nx = dc_point->x; nx < neww; nx++, dstp++)
  176. {
  177. /* Color of pixels:
  178. * c00 c01
  179. * c10 c11 */
  180. rt_uint32_t c00, c01, c10, c11;
  181. int rx, ry, sx, sy;
  182. bx += dx;
  183. by += dy;
  184. if (bx < 0 || by < 0)
  185. continue;
  186. rx = bx / RTGUI_MATRIX_FRAC;
  187. ry = by / RTGUI_MATRIX_FRAC;
  188. if (oriw - 1 <= rx || orih - 1 <= ry)
  189. continue;
  190. c00 = srcp[ry * oriw + rx];
  191. c01 = srcp[ry * oriw + rx + 1];
  192. c10 = srcp[(ry + 1) * oriw + rx];
  193. c11 = srcp[(ry + 1) * oriw + rx + 1];
  194. c00 = (c00 | c00 << 16) & 0x07e0f81f;
  195. c01 = (c01 | c01 << 16) & 0x07e0f81f;
  196. c10 = (c10 | c10 << 16) & 0x07e0f81f;
  197. c11 = (c11 | c11 << 16) & 0x07e0f81f;
  198. /* We down scale the interpolate factor to 5 bits to avoid color
  199. * corruption. */
  200. sx = ((unsigned int)bx % RTGUI_MATRIX_FRAC) >> (RTGUI_MATRIX_FRAC_BITS - 5);
  201. sy = ((unsigned int)by % RTGUI_MATRIX_FRAC) >> (RTGUI_MATRIX_FRAC_BITS - 5);
  202. if (sx)
  203. c00 = ((c01 - c00) * sx / 32 + c00) & 0x07e0f81f;
  204. if (sx && sy)
  205. c10 = ((c11 - c10) * sx / 32 + c10) & 0x07e0f81f;
  206. if (sy)
  207. c00 = ((c10 - c00) * sy / 32 + c00) & 0x07e0f81f;
  208. /* We take the source as a whole and ignore the src->skip. */
  209. *dstp = c00 | (c00 >> 16);
  210. }
  211. dstp += dst->skip - neww;
  212. }
  213. }
  214. union _rgba
  215. {
  216. rt_uint32_t blk;
  217. struct
  218. {
  219. rt_uint8_t r, g, b, a;
  220. } d;
  221. };
  222. /* FrameRect to FrameRect, same format, 4 Bytes/pixel. */
  223. static void _blit_rotate_FR2FR_SF4B(struct _fb_rect* RTGUI_RESTRICT src,
  224. const struct rtgui_point *dc_point,
  225. struct _fb_rect* RTGUI_RESTRICT dst,
  226. const struct rtgui_matrix *invm)
  227. {
  228. rt_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb;
  229. rt_uint32_t* RTGUI_RESTRICT dstp = (rt_uint32_t*)dst->fb;
  230. int neww = dst->width;
  231. int newh = dst->height;
  232. int oriw = src->width;
  233. int orih = src->height;
  234. int nx, ny;
  235. int dx, dy;
  236. dx = invm->m[0];
  237. dy = invm->m[1];
  238. for (ny = dc_point->y; ny < newh; ny++)
  239. {
  240. /* Base x, y. */
  241. int bx, by;
  242. bx = dc_point->x * dx + ny * invm->m[2] + RTGUI_MATRIX_FRAC * invm->m[4];
  243. by = dc_point->x * dy + ny * invm->m[3] + RTGUI_MATRIX_FRAC * invm->m[5];
  244. for (nx = dc_point->x; nx < neww; nx++, dstp++)
  245. {
  246. union _rgba spix, dpix;
  247. int rx, ry, a;
  248. bx += dx;
  249. by += dy;
  250. if (bx < 0 || by < 0)
  251. continue;
  252. rx = bx / RTGUI_MATRIX_FRAC;
  253. ry = by / RTGUI_MATRIX_FRAC;
  254. if (oriw <= rx || orih <= ry)
  255. continue;
  256. spix.blk = srcp[ry * oriw + rx];
  257. /* Down scale the alpha to 5 bits. */
  258. a = spix.d.a >> 3;
  259. if (a == 0)
  260. continue;
  261. if (a == 31)
  262. {
  263. *dstp = spix.blk;
  264. continue;
  265. }
  266. dpix.blk = *dstp;
  267. dpix.d.r = (spix.d.r - dpix.d.r) * a / 32 + dpix.d.r;
  268. dpix.d.g = (spix.d.g - dpix.d.g) * a / 32 + dpix.d.g;
  269. dpix.d.b = (spix.d.b - dpix.d.b) * a / 32 + dpix.d.b;
  270. *dstp = dpix.blk;
  271. }
  272. dstp += dst->skip - neww;
  273. }
  274. }
  275. /* FrameRect to FrameRect, same format, 4 Bytes/pixel, with AA. */
  276. static void _blit_rotate_FR2FR_SF4B_AA(struct _fb_rect* RTGUI_RESTRICT src,
  277. const struct rtgui_point *dc_point,
  278. struct _fb_rect* RTGUI_RESTRICT dst,
  279. const struct rtgui_matrix *invm)
  280. {
  281. rt_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb;
  282. rt_uint32_t* RTGUI_RESTRICT dstp = (rt_uint32_t*)dst->fb;
  283. int neww = dst->width;
  284. int newh = dst->height;
  285. int oriw = src->width;
  286. int orih = src->height;
  287. int nx, ny;
  288. int dx, dy;
  289. dx = invm->m[0];
  290. dy = invm->m[1];
  291. for (ny = dc_point->y; ny < newh; ny++)
  292. {
  293. /* Base x, y. */
  294. int bx, by;
  295. bx = dc_point->x * dx + ny * invm->m[2] + RTGUI_MATRIX_FRAC * invm->m[4];
  296. by = dc_point->x * dy + ny * invm->m[3] + RTGUI_MATRIX_FRAC * invm->m[5];
  297. for (nx = dc_point->x; nx < neww; nx++, dstp++)
  298. {
  299. union _rgba spix00, spix01, spix10, spix11, dpix;
  300. int rx, ry, a, sx, sy;
  301. bx += dx;
  302. by += dy;
  303. if (bx < 0 || by < 0)
  304. continue;
  305. rx = bx / RTGUI_MATRIX_FRAC;
  306. ry = by / RTGUI_MATRIX_FRAC;
  307. if (oriw - 1 <= rx || orih - 1 <= ry)
  308. continue;
  309. spix00.blk = srcp[ry * oriw + rx];
  310. /* Down scale the interpolate factor to 5 bits. */
  311. sx = ((unsigned int)bx % RTGUI_MATRIX_FRAC) >> (RTGUI_MATRIX_FRAC_BITS - 5);
  312. sy = ((unsigned int)by % RTGUI_MATRIX_FRAC) >> (RTGUI_MATRIX_FRAC_BITS - 5);
  313. spix01.blk = srcp[ry * oriw + rx + 1];
  314. spix10.blk = srcp[(ry + 1) * oriw + rx];
  315. spix11.blk = srcp[(ry + 1) * oriw + rx + 1];
  316. if (sx)
  317. spix00.d.a = (spix01.d.a - spix00.d.a) * sx / 32 + spix00.d.a;
  318. if (sx && sy)
  319. spix10.d.a = (spix11.d.a - spix10.d.a) * sx / 32 + spix10.d.a;
  320. if (sy)
  321. spix00.d.a = (spix10.d.a - spix00.d.a) * sy / 32 + spix00.d.a;
  322. a = spix00.d.a >> 3;
  323. if (a == 0)
  324. continue;
  325. if (sx)
  326. {
  327. spix00.d.r = (spix01.d.r - spix00.d.r) * sx / 32 + spix00.d.r;
  328. spix00.d.g = (spix01.d.g - spix00.d.g) * sx / 32 + spix00.d.g;
  329. spix00.d.b = (spix01.d.b - spix00.d.b) * sx / 32 + spix00.d.b;
  330. }
  331. if (sx && sy)
  332. {
  333. spix10.d.r = (spix11.d.r - spix10.d.r) * sx / 32 + spix10.d.r;
  334. spix10.d.g = (spix11.d.g - spix10.d.g) * sx / 32 + spix10.d.g;
  335. spix10.d.b = (spix11.d.b - spix10.d.b) * sx / 32 + spix10.d.b;
  336. }
  337. if (sy)
  338. {
  339. spix00.d.r = (spix10.d.r - spix00.d.r) * sy / 32 + spix00.d.r;
  340. spix00.d.g = (spix10.d.g - spix00.d.g) * sy / 32 + spix00.d.g;
  341. spix00.d.b = (spix10.d.b - spix00.d.b) * sy / 32 + spix00.d.b;
  342. }
  343. if (a == (255 >> 3))
  344. {
  345. *dstp = spix00.blk;
  346. continue;
  347. }
  348. dpix.blk = *dstp;
  349. dpix.d.r = (spix00.d.r - dpix.d.r) * a / 32 + dpix.d.r;
  350. dpix.d.g = (spix00.d.g - dpix.d.g) * a / 32 + dpix.d.g;
  351. dpix.d.b = (spix00.d.b - dpix.d.b) * a / 32 + dpix.d.b;
  352. *dstp = dpix.blk;
  353. }
  354. dstp += dst->skip - neww;
  355. }
  356. }
  357. /* FrameRect to FrameRect, from ARGB8888 to RGB565. */
  358. static void _blit_rotate_FR2FR_ARGB2RGB565(struct _fb_rect* RTGUI_RESTRICT src,
  359. const struct rtgui_point *dc_point,
  360. struct _fb_rect* RTGUI_RESTRICT dst,
  361. const struct rtgui_matrix *invm)
  362. {
  363. rt_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb;
  364. rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->fb;
  365. int neww = dst->width;
  366. int newh = dst->height;
  367. int oriw = src->width;
  368. int orih = src->height;
  369. int nx, ny;
  370. int dx, dy;
  371. dx = invm->m[0];
  372. dy = invm->m[1];
  373. for (ny = dc_point->y; ny < newh; ny++)
  374. {
  375. /* Base x, y. */
  376. int bx, by;
  377. bx = dc_point->x * dx + ny * invm->m[2] + RTGUI_MATRIX_FRAC * invm->m[4];
  378. by = dc_point->x * dy + ny * invm->m[3] + RTGUI_MATRIX_FRAC * invm->m[5];
  379. for (nx = dc_point->x; nx < neww; nx++, dstp++)
  380. {
  381. int rx, ry;
  382. int alpha;
  383. rt_uint32_t op;
  384. bx += dx;
  385. by += dy;
  386. if (bx < 0 || by < 0)
  387. continue;
  388. rx = bx / RTGUI_MATRIX_FRAC;
  389. ry = by / RTGUI_MATRIX_FRAC;
  390. if (oriw <= rx || orih <= ry)
  391. continue;
  392. /* We take the source as a whole and ignore the src->skip. */
  393. op = srcp[ry * oriw + rx];
  394. /* downscale alpha to 5 bits */
  395. alpha = op >> 27;
  396. if (alpha == (255 >> 3))
  397. {
  398. *dstp = (rt_uint16_t)((op >> 8 & 0xf800) +
  399. (op >> 5 & 0x7e0) +
  400. (op >> 3 & 0x1f));
  401. }
  402. else if (alpha != 0)
  403. {
  404. /* We take the source as a whole and ignore the src->skip. */
  405. rt_uint32_t d = *dstp;
  406. /*
  407. * convert source and destination to G0RAB65565
  408. * and blend all components at the same time
  409. */
  410. op = ((op & 0xfc00) << 11) + (op >> 8 & 0xf800)
  411. + (op >> 3 & 0x1f);
  412. d = (d | d << 16) & 0x07e0f81f;
  413. d += (op - d) * alpha >> 5;
  414. d &= 0x07e0f81f;
  415. *dstp = (rt_uint16_t)(d | d >> 16);
  416. }
  417. }
  418. dstp += dst->skip - neww;
  419. }
  420. }
  421. /* FrameRect to FrameRect, from ARGB8888 to RGB565. */
  422. static void _blit_rotate_FR2FR_ARGB2RGB565_AA(struct _fb_rect* RTGUI_RESTRICT src,
  423. const struct rtgui_point *dc_point,
  424. struct _fb_rect* RTGUI_RESTRICT dst,
  425. const struct rtgui_matrix *invm)
  426. {
  427. rt_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb;
  428. rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->fb;
  429. int neww = dst->width;
  430. int newh = dst->height;
  431. int oriw = src->width;
  432. int orih = src->height;
  433. int nx, ny;
  434. int dx, dy;
  435. dx = invm->m[0];
  436. dy = invm->m[1];
  437. for (ny = dc_point->y; ny < newh; ny++)
  438. {
  439. /* Base x, y. */
  440. int bx, by;
  441. bx = dc_point->x * dx + ny * invm->m[2] + RTGUI_MATRIX_FRAC * invm->m[4];
  442. by = dc_point->x * dy + ny * invm->m[3] + RTGUI_MATRIX_FRAC * invm->m[5];
  443. for (nx = dc_point->x; nx < neww; nx++, dstp++)
  444. {
  445. rt_uint32_t op00, op01, op10, op11;
  446. rt_uint8_t a00, a01, a10, a11;
  447. int rx, ry, sx, sy;
  448. bx += dx;
  449. by += dy;
  450. if (bx < 0 || by < 0)
  451. continue;
  452. rx = bx / RTGUI_MATRIX_FRAC;
  453. ry = by / RTGUI_MATRIX_FRAC;
  454. if (oriw - 1 <= rx || orih - 1 <= ry)
  455. continue;
  456. op00 = srcp[ry * oriw + rx];
  457. op01 = srcp[ry * oriw + rx + 1];
  458. op10 = srcp[(ry + 1) * oriw + rx];
  459. op11 = srcp[(ry + 1) * oriw + rx + 1];
  460. /* Down scale the interpolate factor to 5 bits. */
  461. sx = ((unsigned int)bx % RTGUI_MATRIX_FRAC) >> (RTGUI_MATRIX_FRAC_BITS - 5);
  462. sy = ((unsigned int)by % RTGUI_MATRIX_FRAC) >> (RTGUI_MATRIX_FRAC_BITS - 5);
  463. a00 = op00 >> 27;
  464. a01 = op01 >> 27;
  465. a11 = op11 >> 27;
  466. a10 = op10 >> 27;
  467. if (sx)
  468. a00 = (a01 - a00) * sx / 32 + a00;
  469. if (sx && sy)
  470. a10 = (a11 - a10) * sx / 32 + a10;
  471. if (sy)
  472. a00 = (a10 - a00) * sy / 32 + a00;
  473. if (a00 == 0)
  474. continue;
  475. op00 = (((op00 >> 10) & 0x3f) << 21) | (((op00 >> 19) & 0x1f) << 11) | (op00 >> 3 & 0x1f);
  476. op10 = (((op10 >> 10) & 0x3f) << 21) | (((op10 >> 19) & 0x1f) << 11) | (op10 >> 3 & 0x1f);
  477. op01 = (((op01 >> 10) & 0x3f) << 21) | (((op01 >> 19) & 0x1f) << 11) | (op01 >> 3 & 0x1f);
  478. op11 = (((op11 >> 10) & 0x3f) << 21) | (((op11 >> 19) & 0x1f) << 11) | (op11 >> 3 & 0x1f);
  479. if (sx)
  480. {
  481. op00 = ((op01 - op00) * sx / 32 + op00) & 0x07e0f81f;
  482. }
  483. if (sx && sy)
  484. {
  485. op10 = ((op11 - op10) * sx / 32 + op10) & 0x07e0f81f;
  486. }
  487. if (sy)
  488. {
  489. op00 = ((op10 - op00) * sy / 32 + op00) & 0x07e0f81f;
  490. }
  491. if (a00 == (255 >> 3))
  492. {
  493. *dstp = op00 | (op00 >> 16);
  494. }
  495. else if (a00 != 0)
  496. {
  497. rt_uint32_t d = *dstp;
  498. d = (d | d << 16) & 0x07e0f81f;
  499. d += (op00 - d) * a00 >> 5;
  500. d &= 0x07e0f81f;
  501. *dstp = (rt_uint16_t)(d | d >> 16);
  502. }
  503. }
  504. dstp += dst->skip - neww;
  505. }
  506. }
  507. static void _blit_rotate_B2B(struct rtgui_dc_trans *dct,
  508. const struct rtgui_point *dc_point,
  509. struct rtgui_dc_buffer* RTGUI_RESTRICT dest,
  510. struct rtgui_rect *rect,
  511. const struct rtgui_matrix *invm,
  512. int neww, int newh)
  513. {
  514. struct rtgui_rect srcrect;
  515. struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer*)dct->owner;
  516. struct _fb_rect srcfb, dstfb;
  517. rtgui_dc_get_rect(dct->owner, &srcrect);
  518. srcfb.fb = ((struct rtgui_dc_buffer*)dct->owner)->pixel;
  519. srcfb.width = srcrect.x2;
  520. srcfb.height = srcrect.y2;
  521. srcfb.skip = 0;
  522. dstfb.fb = dest->pixel + rtgui_color_get_bpp(dest->pixel_format) * (rect->x1 + rect->y1 * dest->width);
  523. dstfb.width = neww;
  524. dstfb.height = newh;
  525. dstfb.skip = dest->width;
  526. if (dc->pixel_format == dest->pixel_format)
  527. {
  528. switch (rtgui_color_get_bpp(dest->pixel_format)) {
  529. case 2:
  530. if (dct->use_aa)
  531. _blit_rotate_FR2FR_SF2B_AA(&srcfb, dc_point,
  532. &dstfb, invm);
  533. else
  534. _blit_rotate_FR2FR_SF2B(&srcfb, dc_point,
  535. &dstfb, invm);
  536. break;
  537. case 4:
  538. if (dct->use_aa)
  539. _blit_rotate_FR2FR_SF4B_AA(&srcfb, dc_point,
  540. &dstfb, invm);
  541. else
  542. _blit_rotate_FR2FR_SF4B(&srcfb, dc_point,
  543. &dstfb, invm);
  544. break;
  545. default:
  546. rt_kprintf("could not handle bpp: %d\n",
  547. rtgui_color_get_bpp(dest->pixel_format));
  548. return;
  549. }
  550. }
  551. else if (dc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888 &&
  552. dest->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
  553. {
  554. if (dct->use_aa)
  555. _blit_rotate_FR2FR_ARGB2RGB565_AA(&srcfb, dc_point,
  556. &dstfb, invm);
  557. else
  558. _blit_rotate_FR2FR_ARGB2RGB565(&srcfb, dc_point,
  559. &dstfb, invm);
  560. }
  561. else
  562. {
  563. rt_kprintf("not implemented yet\n");
  564. return;
  565. }
  566. }
  567. static void _blit_rotate_B2H(struct rtgui_dc_trans *dct,
  568. const struct rtgui_point *dc_point,
  569. struct rtgui_dc_hw* dest,
  570. struct rtgui_rect *rect,
  571. const struct rtgui_matrix *invm,
  572. int neww, int newh)
  573. {
  574. struct rtgui_rect srcrect;
  575. int start_pix;
  576. struct _fb_rect srcfb, dstfb;
  577. struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer*)dct->owner;
  578. if (dest->hw_driver->framebuffer == RT_NULL)
  579. {
  580. rt_kprintf("Only support framebuffer hw dc\n");
  581. return;
  582. }
  583. rtgui_dc_get_rect(dct->owner, &srcrect);
  584. srcfb.fb = ((struct rtgui_dc_buffer*)dct->owner)->pixel;
  585. srcfb.width = srcrect.x2;
  586. srcfb.height = srcrect.y2;
  587. srcfb.skip = 0;
  588. /* Start point of the widget. */
  589. start_pix = dest->owner->extent.x1 + dest->owner->extent.y1 * dest->hw_driver->width;
  590. /* Start point of the inner rect. */
  591. start_pix += rect->x1 + rect->y1 * dest->hw_driver->width;
  592. dstfb.fb = (void*)(dest->hw_driver->framebuffer
  593. + rtgui_color_get_bpp(dest->hw_driver->pixel_format) * start_pix);
  594. dstfb.width = neww;
  595. dstfb.height = newh;
  596. dstfb.skip = dest->hw_driver->width;
  597. if (dc->pixel_format == dest->hw_driver->pixel_format)
  598. {
  599. switch (rtgui_color_get_bpp(dest->hw_driver->pixel_format)) {
  600. case 2:
  601. if (dct->use_aa)
  602. _blit_rotate_FR2FR_SF2B_AA(&srcfb, dc_point,
  603. &dstfb, invm);
  604. else
  605. _blit_rotate_FR2FR_SF2B(&srcfb, dc_point,
  606. &dstfb, invm);
  607. break;
  608. case 4:
  609. if (dct->use_aa)
  610. _blit_rotate_FR2FR_SF4B_AA(&srcfb, dc_point,
  611. &dstfb, invm);
  612. else
  613. _blit_rotate_FR2FR_SF4B(&srcfb, dc_point,
  614. &dstfb, invm);
  615. break;
  616. default:
  617. rt_kprintf("could not handle bpp: %d\n",
  618. rtgui_color_get_bpp(dest->hw_driver->pixel_format));
  619. return;
  620. }
  621. }
  622. else if (dc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888 &&
  623. dest->hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
  624. {
  625. if (dct->use_aa)
  626. _blit_rotate_FR2FR_ARGB2RGB565_AA(&srcfb, dc_point,
  627. &dstfb, invm);
  628. else
  629. _blit_rotate_FR2FR_ARGB2RGB565(&srcfb, dc_point,
  630. &dstfb, invm);
  631. }
  632. else
  633. {
  634. rt_kprintf("not implemented yet\n");
  635. return;
  636. }
  637. }
  638. void rtgui_dc_trans_blit(struct rtgui_dc_trans *dct,
  639. struct rtgui_point *dc_point,
  640. struct rtgui_dc *dest,
  641. struct rtgui_rect *rect)
  642. {
  643. struct rtgui_rect bkrect;
  644. struct rtgui_matrix invm;
  645. struct rtgui_point dp;
  646. int neww, newh;
  647. RT_ASSERT(dct);
  648. RT_ASSERT(dest);
  649. if (dc_point == RT_NULL)
  650. {
  651. dp.x = dp.y = 0;
  652. dc_point = &dp;
  653. }
  654. if (rect == RT_NULL)
  655. {
  656. rtgui_dc_get_rect(dest, &bkrect);
  657. rect = &bkrect;
  658. }
  659. rtgui_dc_trans_get_new_wh(dct, &neww, &newh);
  660. if (dc_point->x < 0)
  661. {
  662. neww -= dc_point->x;
  663. if (neww < 0)
  664. return;
  665. dc_point->x = 0;
  666. }
  667. else if (dc_point->x > neww)
  668. return;
  669. if (dc_point->y < 0)
  670. {
  671. newh -= dc_point->y;
  672. if (newh < 0)
  673. return;
  674. dc_point->y = 0;
  675. }
  676. else if (dc_point->y > newh)
  677. return;
  678. if (rtgui_matrix_inverse(&dct->m, &invm))
  679. return;
  680. if (rtgui_rect_width(*rect) < neww - dc_point->x)
  681. neww = dc_point->x + rtgui_rect_width(*rect);
  682. if (rtgui_rect_height(*rect) < newh - dc_point->y)
  683. newh = dc_point->y + rtgui_rect_height(*rect);
  684. /* Route to different optimized routines. */
  685. if (dct->owner->type == RTGUI_DC_BUFFER)
  686. {
  687. if (dest->type == RTGUI_DC_BUFFER)
  688. _blit_rotate_B2B(dct, dc_point,
  689. (struct rtgui_dc_buffer*)dest,
  690. rect, &invm, neww, newh);
  691. else if (dest->type == RTGUI_DC_HW)
  692. _blit_rotate_B2H(dct, dc_point,
  693. (struct rtgui_dc_hw*)dest,
  694. rect, &invm, neww, newh);
  695. else if (dest->type == RTGUI_DC_CLIENT)
  696. // TODO:
  697. ;
  698. else
  699. rt_kprintf("unknown dc for dc_trans\n");
  700. }
  701. else
  702. rt_kprintf("not implemented yet\n");
  703. }
  704. RTM_EXPORT(rtgui_dc_trans_blit);