TDrawHelpers.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /*
  2. * Copyright (c) 2010 Nokia Corporation.
  3. */
  4. #include "TDrawHelpers.h"
  5. #include "TMath.h"
  6. #include <string.h>
  7. CTDrawHelpers::CTDrawHelpers(void)
  8. {
  9. }
  10. CTDrawHelpers::~CTDrawHelpers(void)
  11. {
  12. }
  13. TSDWORD CTDrawHelpers::linearScaleImage( CTSurface_RGBA8888 *source, CTSurface_RGBA8888 *target, TSDWORD type )
  14. {
  15. TSDWORD r,g,b;
  16. TBYTE xoffset;
  17. TBYTE yoffset;
  18. TSDWORD fixedyinc = (source->getHeight()<<8) / target->getHeight();
  19. TSDWORD fixedxinc = (source->getWidth()<<8) / target->getWidth();
  20. TSDWORD fixedy=fixedyinc/2;
  21. TSDWORD p;
  22. TDWORD *t = (TDWORD*)target->getData();
  23. TSDWORD y = 0;
  24. while (y<target->getHeight()) {
  25. TSDWORD fixedx = fixedxinc/2;
  26. yoffset = (TBYTE)(fixedy&255);
  27. TDWORD *s_horline1 = (TDWORD*)source->getData() + source->getPitch() * (fixedy>>8);
  28. TDWORD *s_horline2 = s_horline1 + source->getPitch();
  29. TDWORD *t_horline = t;
  30. TDWORD *t_horline_target = t+target->getWidth();
  31. while (t_horline != t_horline_target) {
  32. p = (fixedx>>8);
  33. xoffset = (TBYTE)(fixedx&255);
  34. r = ((((( ((s_horline1[p]>>0)&255)*((TBYTE)~xoffset) + ((s_horline1[p+1]>>0)&255)*xoffset ) ) * ((TBYTE)~yoffset) ) +
  35. ((( ((s_horline2[p]>>0)&255)*((TBYTE)~xoffset) + ((s_horline2[p+1]>>0)&255)*xoffset ) ) * (yoffset) )) >> 16);
  36. g = ((((( ((s_horline1[p]>>8)&255)*((TBYTE)~xoffset) + ((s_horline1[p+1]>>8)&255)*xoffset ) ) * ((TBYTE)~yoffset) ) +
  37. ((( ((s_horline2[p]>>8)&255)*((TBYTE)~xoffset) + ((s_horline2[p+1]>>8)&255)*xoffset ) ) * (yoffset) )) >> 16);
  38. b = ((((( ((s_horline1[p]>>16)&255)*((TBYTE)~xoffset) + ((s_horline1[p+1]>>16)&255)*xoffset ) ) * ((TBYTE)~yoffset) ) +
  39. ((( ((s_horline2[p]>>16)&255)*((TBYTE)~xoffset) + ((s_horline2[p+1]>>16)&255)*xoffset ) ) * (yoffset) )) >> 16);
  40. *t_horline = (r | (g<<8) | (b<<16) );
  41. t_horline++;
  42. fixedx+=fixedxinc;
  43. };
  44. t += target->getPitch();
  45. y++;;
  46. fixedy += fixedyinc;
  47. };
  48. return 1;
  49. };
  50. void CTDrawHelpers::rotateBlit( CTSurface_RGBA8888*target, CTSurface_RGBA8888 *source,
  51. TSDWORD middlex, TSDWORD middley,TSDWORD vx, TSDWORD vy,
  52. TDWORD col, eTBLITOPERATION o )
  53. {
  54. TSDWORD temp;
  55. TSDWORD x1,y1,x2,y2,nx,ny;
  56. TSDWORD leftx,lefty,rightx,righty;
  57. temp = (source->getWidth()<<FP_BITS) / source->getHeight();
  58. if (vy>0) {
  59. nx = tmath_fpmul( -vy, temp );
  60. ny = tmath_fpmul( vx, temp );
  61. x1 = (middlex - vx);
  62. y1 = (middley - vy);
  63. x2 = (middlex + vx);
  64. y2 = (middley + vy);
  65. if (ny>0) {
  66. leftx = x1+nx;
  67. lefty = y1+ny;
  68. rightx = x1-nx+vx*2;
  69. righty = y1-ny+vy*2;
  70. } else {
  71. leftx = x1+nx + vx*2;
  72. lefty = y1+ny + vy*2;
  73. rightx = x1-nx;
  74. righty = y1-ny;
  75. nx=-nx; ny=-ny;
  76. }
  77. } else {
  78. nx = tmath_fpmul( vy, temp );
  79. ny = tmath_fpmul( -vx, temp );
  80. x1 = (middlex + vx);
  81. y1 = (middley + vy);
  82. x2 = (middlex - vx);
  83. y2 = (middley - vy);
  84. if (ny>0) {
  85. leftx = x1+nx;
  86. lefty = y1+ny;
  87. rightx = x1-nx-vx*2;
  88. righty = y1-ny-vy*2;
  89. } else {
  90. leftx = x1+nx - vx*2;
  91. lefty = y1+ny - vy*2;
  92. rightx = x1-nx;
  93. righty = y1-ny;
  94. nx=-nx; ny=-ny;
  95. }
  96. }
  97. x1 -= nx; y1 -= ny;
  98. x2 += nx; y2 += ny;
  99. TSDWORD leftxinc = tmath_fpdiv( leftx-x1, (lefty-y1)+1 );
  100. TSDWORD rightxinc = tmath_fpdiv( rightx-x1, (righty-y1)+1 );
  101. // subpixel, and yclipping
  102. //TSDWORD intery = (tmath_fixedCeil( y1 )<<FP_BITS) - FP_VAL/2;
  103. TSDWORD intery = ((y1>>FP_BITS)<<FP_BITS) + FP_VAL/2;
  104. if (intery<0) intery=0;
  105. temp = intery-y1;
  106. TSDWORD interx_left = x1+tmath_fpmul( leftxinc, temp );
  107. TSDWORD interx_right = x1+tmath_fpmul( rightxinc, temp );
  108. __int64 juu = ((__int64)vx*(__int64)vx + (__int64)vy*(__int64)vy)>>FP_BITS;
  109. juu+=(juu>>8);
  110. vx = (TSDWORD)(((__int64)(vx * source->getHeight())<<13) / (__int64)juu );
  111. vy = (TSDWORD)(((__int64)(vy * source->getHeight())<<13) / (__int64)juu );
  112. nx = vy;
  113. ny = -vx;
  114. TSDWORD rasx;
  115. TDWORD *s = (TDWORD*)source->getData();
  116. TDWORD *t, *t_target;
  117. // rasterize.
  118. while (intery<y2 && intery<(target->getHeight()<<FP_BITS)) {
  119. if (intery>lefty) {
  120. leftxinc = tmath_fpdiv( x2-leftx,y2-lefty+1 );
  121. interx_left = leftx + tmath_fpmul( leftxinc, intery-lefty+1 );
  122. lefty=y2; // never do this again
  123. };
  124. if (intery>righty) {
  125. rightxinc = tmath_fpdiv( x2-rightx, y2-righty+1 );
  126. interx_right = rightx + tmath_fpmul( rightxinc, intery-righty+1 );
  127. righty = y2; // never do this again.
  128. };
  129. x1 = (source->getHeight()<<13) +
  130. tmath_fpmul( intery-middley, nx ) +
  131. tmath_fpmul( interx_left-middlex, vx );
  132. y1 = (source->getWidth()<<13) +
  133. tmath_fpmul( intery-middley, ny ) +
  134. tmath_fpmul( interx_left-middlex, vy );
  135. // NOTE, ADD SUBTEXEL ACCURACY IN INNER LOOP
  136. rasx = tmath_fixedCeil( interx_left );
  137. if (rasx<0) rasx = 0;
  138. temp = (rasx<<FP_BITS)-interx_left;
  139. x1 += tmath_fpmul( vx, temp );
  140. y1 += tmath_fpmul( vy, temp );
  141. temp = tmath_fixedCeil(interx_right);
  142. if (temp>target->getWidth()) temp = target->getWidth();
  143. if (temp>rasx) {
  144. TDWORD c;
  145. t = (TDWORD*)target->getData() + (intery>>FP_BITS)*target->getPitch();
  146. t_target = t+temp;
  147. t+=rasx;
  148. switch (o) {
  149. default:
  150. case eTBLITOPERATION_ALPHA:
  151. case eTBLITOPERATION_FASTALPHA:
  152. while (t!=t_target) {
  153. {
  154. //if (x1>0 && y1>0 && x1<source->getHeight() << FP_BITS && y1<source->getWidth() << FP_BITS) {
  155. c= s[ (x1>>FP_BITS) * source->getPitch() + ((y1>>FP_BITS)) ];
  156. temp = ((c>>24) * ((col>>24)+1)) >> 8;
  157. if (temp>0) {
  158. if (temp<255) {
  159. *t = (((((c&255)*temp) + ((*t)&255)*(255^temp)) >> 8)) |
  160. ((((((c>>8)&255)*temp) + (((*t)>>8)&255)*(255^temp)) >> 8)<<8) |
  161. ((((((c>>16)&255)*temp) + (((*t)>>16)&255)*(255^temp)) >> 8)<<16);
  162. } else {
  163. *t = (c&0x00FFFFFF);
  164. }
  165. };
  166. //} else *t = 0xFFFFFFFF;
  167. }
  168. //*t=0xFFFFFFFF;
  169. x1 += vx;
  170. y1 += vy;
  171. t++;
  172. };
  173. break;
  174. case eTBLITOPERATION_ADD:
  175. {
  176. TSDWORD rr,gg,bb;
  177. while (t!=t_target) {
  178. //if (x1<0 || y1<0) _asm int 3;
  179. //if (x1>=source->getWidth()*FP_VAL || y1>source->getHeight()*FP_VAL) _asm int 3;
  180. {
  181. c= s[ (x1>>FP_BITS) * source->getPitch() + ((y1>>FP_BITS)) ];
  182. rr = ((((c>>0)&255) * ((col>>0)&255) )>>8) + ((*t>>0)&255);
  183. if (rr>255) rr= 255;
  184. gg = ((((c>>8)&255) * ((col>>8)&255) )>>8) + ((*t>>8)&255);
  185. if (gg>255) gg= 255;
  186. bb = ((((c>>16)&255) * ((col>>16)&255) )>>8) + ((*t>>16)&255);
  187. if (bb>255) bb= 255;
  188. *t = rr | (gg<<8) | (bb<<16);
  189. }
  190. x1 += vx;
  191. y1 += vy;
  192. t++;
  193. };
  194. }
  195. break;
  196. }
  197. }
  198. interx_left += leftxinc;
  199. interx_right += rightxinc;
  200. intery+=FP_VAL;
  201. }
  202. };
  203. CTBaseSurface* CTDrawHelpers::qualityShrink( CTBaseSurface *source, TSDWORD sizeDiv, eTSURFACEFORMAT returnFormat ) {
  204. if (!source) return 0;
  205. TSDWORD newWidth = source->getWidth() / sizeDiv;
  206. TSDWORD newHeight = source->getHeight() / sizeDiv;
  207. if (newWidth<1 || newHeight<1) return 0;
  208. //if (source->getFormat() != eTSURFACEFORMAT_RGBA8888) return 0;
  209. CTBaseSurface *rval = new CTBaseSurface();
  210. rval->create( newWidth, newHeight, returnFormat );
  211. TSDWORD compmul = 65536 / (sizeDiv*sizeDiv);
  212. TSDWORD r,g,b,a;
  213. TDWORD *target = (TDWORD*)rval->getData();
  214. for (int ty = 0; ty<rval->getHeight(); ty++) {
  215. switch ( source->getFormat() ) {
  216. default: break;
  217. case eTSURFACEFORMAT_RGBA8888:
  218. {
  219. TDWORD *s;
  220. TDWORD *s_target, *sy_target;
  221. for (int tx = 0; tx<rval->getWidth(); tx++) {
  222. r=0;g=0;b=0; a=0;
  223. s = ((TDWORD*)source->getData()) + source->getPitch()*ty*sizeDiv + tx*sizeDiv;
  224. sy_target = s+source->getPitch()*sizeDiv;
  225. while (sy_target!=s) {
  226. s_target = s + sizeDiv;
  227. while (s!=s_target) {
  228. r += (*s&255);
  229. g += ((*s>>8)&255);
  230. b += ((*s>>16)&255);
  231. a += ((*s>>24)&255);
  232. s++;
  233. };
  234. s-=sizeDiv;
  235. s+=source->getPitch();
  236. }
  237. r = ((r*compmul)>>16);
  238. g = ((g*compmul)>>16);
  239. b = ((b*compmul)>>16);
  240. a = ((a*compmul)>>16);
  241. //*target = (b>>3) | ((g>>2)<<5) | ((r>>3)<<11);
  242. *target = r | (g<<8) | (b<<16) | (a<<24);
  243. target++;
  244. }
  245. }
  246. break;
  247. case eTSURFACEFORMAT_RGB888:
  248. {
  249. TBYTE *s;
  250. TBYTE *s_target, *sy_target;
  251. for (int tx = 0; tx<rval->getWidth(); tx++) {
  252. r=0;g=0;b=0;
  253. s = ((TBYTE*)source->getData()) + (source->getPitch()*ty*sizeDiv + tx*sizeDiv)*3;
  254. sy_target = s+source->getPitch()*sizeDiv*3;
  255. while (sy_target!=s) {
  256. s_target = s + sizeDiv*3;
  257. while (s!=s_target) {
  258. r += (s[0]&255);
  259. g += (s[1]&255);
  260. b += (s[2]&255);
  261. s+=3;
  262. };
  263. s-=sizeDiv*3;
  264. s+=source->getPitch()*3;
  265. }
  266. r = ((r*compmul)>>16);
  267. g = ((g*compmul)>>16);
  268. b = ((b*compmul)>>16);
  269. *target = (b>>3) | ((g>>2)<<5) | ((r>>3)<<11);
  270. target++;
  271. }
  272. }
  273. break;
  274. } // endof switch
  275. };
  276. return rval;
  277. };