Image.cpp 88 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124
  1. //---Include---
  2. #include "Image.h"
  3. #ifdef WIN32
  4. # include <objidl.h>
  5. #endif
  6. #include "AlphaField.h"
  7. #include "Border.h"
  8. #include "FileSystem.h"
  9. #include "Globals.h"
  10. #include "MouseEvent.h"
  11. #include "Scroll.h"
  12. #include "Text.h"
  13. #include "ToolTip.h"
  14. #ifdef WIN32
  15. # include <gdiplus.h>
  16. # pragma comment(lib, "gdiplus.lib")
  17. #endif
  18. #ifndef WIN32
  19. # include <math.h>
  20. # include <stdlib.h>
  21. # include <string.h>
  22. # ifndef max
  23. # define max(a, b) (((a) > (b)) ? (a) : (b))
  24. # endif
  25. # ifndef min
  26. # define min(a, b) (((a) < (b)) ? (a) : (b))
  27. # endif
  28. #endif
  29. using namespace Framework;
  30. // Contents of the Image class from Image.h
  31. // Constructor
  32. Image::Image(bool options)
  33. : ReferenceCounter(),
  34. fc(0),
  35. delFc(1),
  36. size(0, 0),
  37. drawOff(options ? new Point[2000] : new Point[1]),
  38. dPosA(options ? new Point[2000] : new Point[1]),
  39. dSizeA(options ? new Point[2000] : new Point[1]),
  40. doa(0),
  41. alpha(options ? new unsigned char[1000] : new unsigned char[1]),
  42. alphaCount(0),
  43. rend(0),
  44. alpha3D(0)
  45. {
  46. alpha[0] = 0;
  47. }
  48. // Destructor
  49. Image::~Image()
  50. {
  51. if (delFc)
  52. {
  53. delete[] fc;
  54. fc = 0;
  55. }
  56. delete[] dPosA;
  57. delete[] dSizeA;
  58. delete[] alpha;
  59. delete[] drawOff;
  60. }
  61. // privat
  62. inline void Image::alphaPixelP(int x, int y, int f)
  63. {
  64. alphaPixelP(fc[x + y * size.x], f);
  65. }
  66. inline void Image::alphaPixelP3D(int x, int y, int f)
  67. {
  68. alphaPixelP3D(fc[x + y * size.x], f);
  69. }
  70. inline void Image::alphaPixelAssozP(int& fc, int f)
  71. {
  72. unsigned char* fc1 = (unsigned char*)&fc;
  73. unsigned char* fc2 = (unsigned char*)&f;
  74. unsigned char na = (unsigned char)~fc2[3];
  75. unsigned char a = (unsigned char)(fc2[3] + ((na * fc1[3]) >> 8));
  76. if (a == 0) return;
  77. fc1[2] = (unsigned char)((fc2[2] * fc2[3] + ((fc1[2] * na * fc1[3]) >> 8))
  78. / a);
  79. fc1[1] = (unsigned char)((fc2[1] * fc2[3] + ((fc1[1] * na * fc1[3]) >> 8))
  80. / a);
  81. fc1[0] = (unsigned char)((fc2[0] * fc2[3] + ((fc1[0] * na * fc1[3]) >> 8))
  82. / a);
  83. fc1[3] = a;
  84. }
  85. inline void Image::alphaPixelP3D(int& fc, int colorb)
  86. {
  87. int alpha = ((colorb >> 24) & 0xFF);
  88. int oldAlpha = ((fc >> 24) & 0xFF);
  89. bool newAlpha = alpha > oldAlpha;
  90. int na = (0x100 - alpha);
  91. fc = (((((na * (fc & 0xFF00FF)) >> 8)
  92. + ((alpha * (colorb & 0xFF00FF)) >> 8))
  93. & 0xFF00FF)
  94. | ((((na * (fc & 0x00FF00)) >> 8)
  95. + ((alpha * (colorb & 0x00FF00)) >> 8))
  96. & 0x00FF00)
  97. | ((colorb & 0xFF000000) * newAlpha)
  98. | ((fc & 0xFF000000) * !newAlpha))
  99. * (fc != 0)
  100. | (fc == 0) * colorb;
  101. }
  102. inline void Image::alphaPixelP(int& fc, int colorb)
  103. {
  104. int alpha = ((colorb >> 24) & 0xFF);
  105. int na = (0x100 - alpha);
  106. fc = ((((na * (fc & 0xFF00FF)) >> 8) + ((alpha * (colorb & 0xFF00FF)) >> 8))
  107. & 0xFF00FF)
  108. | ((((na * (fc & 0x00FF00)) >> 8) + ((alpha * (colorb & 0x00FF00)) >> 8))
  109. & 0x00FF00)
  110. | ((fc & 0xFF000000));
  111. }
  112. char Image::getOutCode(Point p) const
  113. {
  114. char ret = 0;
  115. if (p.x < dPosA[doa].x) ret = 1;
  116. if (p.x >= dSizeA[doa].x) ret = 2;
  117. if (p.y < dPosA[doa].y) ret |= 4;
  118. if (p.y >= dSizeA[doa].y) ret |= 8;
  119. return ret;
  120. }
  121. void Image::drawFlatTriangle(
  122. int y1, int y2, float m1, float b1, float m2, float b2, int color)
  123. {
  124. const int yStart = max(y1, dPosA[doa].y);
  125. const int yEnd = min(y2, dSizeA[doa].y);
  126. for (int y = yStart; y < yEnd; y++)
  127. {
  128. const int xStart = max((int)(m1 * (float)y + b1 + 0.5f), dPosA[doa].x);
  129. const int xEnd = min((int)(m2 * (float)y + b2 + 0.5f), dSizeA[doa].x);
  130. for (int x = xStart; x < xEnd; x++)
  131. fc[x + y * size.x] = color;
  132. }
  133. }
  134. void Image::drawFlatTriangleTexture(int y1,
  135. int y2,
  136. double m1,
  137. double b1,
  138. double m2,
  139. double b2,
  140. double tx1,
  141. double ty1,
  142. double tx2,
  143. double ty2,
  144. double tx_1o,
  145. double ty_1o,
  146. double tx_2o,
  147. double ty_2o,
  148. double txf,
  149. double tyf,
  150. const Image& textur)
  151. {
  152. const double yStart = max(y1, dPosA[doa].y);
  153. const double yEnd = min(y2, dSizeA[doa].y);
  154. double tx_1 = tx1 + tx_1o * (yStart - y1),
  155. ty_1 = ty1 + ty_1o * (yStart - y1),
  156. tx_2 = tx2 + tx_2o * (yStart - y1),
  157. ty_2 = ty2 + ty_2o * (yStart - y1);
  158. for (double y = yStart; y < yEnd;
  159. y++, tx_1 += tx_1o, ty_1 += ty_1o, tx_2 += tx_2o, ty_2 += ty_2o)
  160. {
  161. const double xStart = m1 * y + b1;
  162. const double xEnd = m2 * y + b2;
  163. drawLineHTexture(Vec2<double>(xStart, y),
  164. xEnd - xStart,
  165. Vec2<double>(tx_1, ty_1),
  166. Vec2<double>(tx_2, ty_2),
  167. txf,
  168. tyf,
  169. textur);
  170. }
  171. }
  172. void Image::drawFlatTriangleAlpha(
  173. int y1, int y2, float m1, float b1, float m2, float b2, int color)
  174. {
  175. const int yStart = max((int)(y1 + 0.5), dPosA[doa].y);
  176. const int yEnd = min((int)(y2 + 0.5), dSizeA[doa].y);
  177. if (alpha3D)
  178. {
  179. for (int y = yStart; y < yEnd; y++)
  180. {
  181. const int xStart
  182. = max((int)(m1 * ((float)y + 0.5f) + b1 + 0.5f), dPosA[doa].x);
  183. const int xEnd
  184. = min((int)(m2 * ((float)y + 0.5) + b2 + 0.5f), dSizeA[doa].x);
  185. for (int x = xStart; x < xEnd; x++)
  186. alphaPixelP3D(fc[x + y * size.x], color);
  187. }
  188. }
  189. else
  190. {
  191. for (int y = yStart; y < yEnd; y++)
  192. {
  193. const int xStart
  194. = max((int)(m1 * ((float)y + 0.5f) + b1 + 0.5f), dPosA[doa].x);
  195. const int xEnd
  196. = min((int)(m2 * ((float)y + 0.5) + b2 + 0.5f), dSizeA[doa].x);
  197. for (int x = xStart; x < xEnd; x++)
  198. alphaPixelP(fc[x + y * size.x], color);
  199. }
  200. }
  201. }
  202. void Image::drawFlatTriangleTextureAlpha(int y1,
  203. int y2,
  204. double m1,
  205. double b1,
  206. double m2,
  207. double b2,
  208. double tx1,
  209. double ty1,
  210. double tx2,
  211. double ty2,
  212. double tx_1o,
  213. double ty_1o,
  214. double tx_2o,
  215. double ty_2o,
  216. double txf,
  217. double tyf,
  218. const Image& textur)
  219. {
  220. const double yStart = max(y1, dPosA[doa].y);
  221. const double yEnd = min(y2, dSizeA[doa].y);
  222. double tx_1 = tx1 + tx_1o * (yStart - y1),
  223. ty_1 = ty1 + ty_1o * (yStart - y1),
  224. tx_2 = tx2 + tx_2o * (yStart - y1),
  225. ty_2 = ty2 + ty_2o * (yStart - y1);
  226. for (double y = yStart; y < yEnd;
  227. y++, tx_1 += tx_1o, ty_1 += ty_1o, tx_2 += tx_2o, ty_2 += ty_2o)
  228. {
  229. const double xStart = m1 * y + b1;
  230. const double xEnd = m2 * y + b2;
  231. drawLineHTextureAlpha(Vec2<double>(xStart, y),
  232. xEnd - xStart,
  233. Vec2<double>(tx_1, ty_1),
  234. Vec2<double>(tx_2, ty_2),
  235. txf,
  236. tyf,
  237. textur);
  238. }
  239. }
  240. void Image::drawLineHTexture(Vec2<double> p,
  241. double len,
  242. Vec2<double> ta,
  243. Vec2<double> tb,
  244. double txo,
  245. double tyo,
  246. const Image& textur) // draws a horizontal line
  247. {
  248. if (alpha[alphaCount] == 0xFF) return;
  249. if (alpha[alphaCount])
  250. {
  251. drawLineHTextureAlpha(p, len, ta, tb, txo, tyo, textur);
  252. return;
  253. }
  254. if (len < 0)
  255. {
  256. p.x += len;
  257. len = -len;
  258. ta.Swap(tb);
  259. }
  260. int dpx = dPosA[doa].x;
  261. int dpy = dPosA[doa].y;
  262. int dgx = dSizeA[doa].x;
  263. int dgy = dSizeA[doa].y;
  264. if (p.y < dpy || p.y >= dgy) return;
  265. double off = 0;
  266. if (p.x < dpx)
  267. {
  268. off = dpx - p.x;
  269. len -= dpx - p.x;
  270. if (len <= 0) return;
  271. p.x = dpx;
  272. }
  273. if (p.x + len >= dgx)
  274. {
  275. len -= p.x - dgx + len;
  276. if (len <= 0) return;
  277. }
  278. int br = size.x;
  279. int* fc = this->fc + (int)(p.x + (int)p.y * br);
  280. double x = ta.x + txo * off, y = ta.y + tyo * off;
  281. int* buffer = textur.getBuffer();
  282. int txtBr = textur.getWidth();
  283. for (int i = 0; i < len; ++i, ++fc)
  284. {
  285. *fc = buffer[(int)((int)(x + 0.5) + (int)(y + 0.5) * txtBr)];
  286. x += txo, y += tyo;
  287. }
  288. rend = 1;
  289. }
  290. void Image::drawLineHTextureAlpha(Vec2<double> p,
  291. double len,
  292. Vec2<double> ta,
  293. Vec2<double> tb,
  294. double txo,
  295. double tyo,
  296. const Image& textur) // draws a horizontal line
  297. {
  298. if (alpha[alphaCount] == 0xFF) return;
  299. if (len < 0)
  300. {
  301. p.x += len;
  302. len = -len;
  303. ta.Swap(tb);
  304. }
  305. int dpx = dPosA[doa].x;
  306. int dpy = dPosA[doa].y;
  307. int dgx = dSizeA[doa].x;
  308. int dgy = dSizeA[doa].y;
  309. if (p.y < dpy || p.y >= dgy) return;
  310. double off = 0;
  311. if (p.x < dpx)
  312. {
  313. off = dpx - p.x;
  314. len -= dpx - p.x;
  315. if (len <= 0) return;
  316. p.x = dpx;
  317. }
  318. if (p.x + len >= dgx)
  319. {
  320. len -= p.x - dgx + len;
  321. if (len <= 0) return;
  322. }
  323. int br = size.x;
  324. int* fc = this->fc + (int)(p.x + (int)p.y * br);
  325. double x = ta.x + txo * off, y = ta.y + tyo * off;
  326. int* buffer = textur.getBuffer();
  327. int txtBr = textur.getWidth();
  328. int f;
  329. if (alpha3D)
  330. {
  331. for (int i = 0; i < len; ++i, ++fc)
  332. {
  333. f = buffer[(int)((int)(x + 0.5) + (int)(y + 0.5) * txtBr)];
  334. if (alpha[alphaCount])
  335. {
  336. unsigned char* cf = (unsigned char*)&f;
  337. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  338. * (cf[3] - alpha[alphaCount]));
  339. }
  340. alphaPixelP3D(*fc, f);
  341. x += txo, y += tyo;
  342. }
  343. }
  344. else
  345. {
  346. for (int i = 0; i < len; ++i, ++fc)
  347. {
  348. f = buffer[(int)((int)(x + 0.5) + (int)(y + 0.5) * txtBr)];
  349. if (alpha[alphaCount])
  350. {
  351. unsigned char* cf = (unsigned char*)&f;
  352. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  353. * (cf[3] - alpha[alphaCount]));
  354. }
  355. alphaPixelP(*fc, f);
  356. x += txo, y += tyo;
  357. }
  358. }
  359. rend = 1;
  360. }
  361. // non-constant
  362. // Checks if a rectangle is fully or partially within the drawing area.
  363. // return 0 if the rectangle is not in the drawing area, 1 otherwise
  364. bool Image::isAreaDrawable(int x, int y, int b, int h)
  365. {
  366. int dpx = dPosA[doa].x;
  367. int dpy = dPosA[doa].y;
  368. int dgx = dSizeA[doa].x;
  369. int dgy = dSizeA[doa].y;
  370. x += drawOff[doa].x;
  371. y += drawOff[doa].y;
  372. if (x + b < dpx || y + h < dpy || x >= dgx || y >= dgy) return 0;
  373. return 1;
  374. }
  375. // When this flag is set, during alpha blending if the previous
  376. // color is 0, only the new one is copied with its alpha value. This is useful
  377. // for use in the 3D screen, where the drawn image is later displayed using
  378. // alpha blending
  379. void Image::setAlpha3D(bool erlaubt)
  380. {
  381. alpha3D = erlaubt;
  382. }
  383. void Image::setAlpha(
  384. unsigned char alpha) // sets the transparency for subsequent drawings
  385. {
  386. int last = this->alpha[alphaCount];
  387. ++alphaCount;
  388. assert(alphaCount < 1000);
  389. this->alpha[alphaCount]
  390. = (unsigned char)((255 - alpha) > last ? (255 - alpha) : last);
  391. }
  392. void Image::releaseAlpha() // Releases alpha
  393. {
  394. --alphaCount;
  395. }
  396. void Image::setPixelBuffer(int* buffer,
  397. bool deleteBuffer,
  398. int Width,
  399. int height) // sets the pointer to the image pixels
  400. {
  401. if (delFc) delete[] fc;
  402. fc = buffer;
  403. delFc = deleteBuffer;
  404. size.x = Width;
  405. size.y = height;
  406. drawOff[0].x = 0;
  407. drawOff[0].y = 0;
  408. dPosA[0].x = 0;
  409. dPosA[0].y = 0;
  410. dSizeA[0] = size;
  411. alphaCount = 0;
  412. alpha[0] = 0;
  413. doa = 0;
  414. rend = 1;
  415. }
  416. void Image::newImage(int Width, int height, int fillColor)
  417. {
  418. if (fc && delFc) delete[] fc;
  419. size.x = Width;
  420. size.y = height;
  421. fc = new int[size.x * size.y];
  422. setColor(fillColor);
  423. drawOff[0].x = 0;
  424. drawOff[0].y = 0;
  425. dPosA[0].x = 0;
  426. dPosA[0].y = 0;
  427. dSizeA[0] = size;
  428. alphaCount = 0;
  429. alpha[0] = 0;
  430. doa = 0;
  431. rend = 1;
  432. }
  433. void Image::setColor(int f)
  434. {
  435. if ((f & 0xFF) == ((f >> 8) & 0xFF) && (f & 0xFF) == ((f >> 16) & 0xFF)
  436. && (f & 0xFF) == ((f >> 24) & 0xFF))
  437. memset(fc, f, size.x * size.y * 4);
  438. else
  439. {
  440. for (int *i = fc, *end = i + size.x * size.y; i < end; i++)
  441. *i = f;
  442. }
  443. rend = 1;
  444. }
  445. void Image::fillRegion(int x, int y, int b, int h, int ff)
  446. {
  447. if (alpha[alphaCount] == 0xFF) return;
  448. if (alpha[alphaCount])
  449. {
  450. alphaRegion(x, y, b, h, ff);
  451. return;
  452. }
  453. int dpx = dPosA[doa].x;
  454. int dpy = dPosA[doa].y;
  455. int dgx = dSizeA[doa].x;
  456. int dgy = dSizeA[doa].y;
  457. x += drawOff[doa].x;
  458. y += drawOff[doa].y;
  459. if (x + b < dpx || y + h < dpy || x >= dgx || y >= dgy) return;
  460. if (x < dpx)
  461. {
  462. b -= dpx - x;
  463. x = dpx;
  464. }
  465. if (y < dpy)
  466. {
  467. h -= dpy - y;
  468. y = dpy;
  469. }
  470. b = (x + b) >= dgx ? (dgx - x) : b;
  471. h = (y + h) >= dgy ? (dgy - y) : h;
  472. int* pixel = fc + y * size.x + x;
  473. int* rowEnd = pixel + b;
  474. for (int i = 0; i < h; pixel += size.x - b, ++i, rowEnd += size.x)
  475. {
  476. for (; pixel < rowEnd; ++pixel)
  477. *pixel = ff;
  478. }
  479. rend = 1;
  480. }
  481. void Image::alphaRegion(int x, int y, int b, int h, int ff)
  482. {
  483. if (alpha[alphaCount] == 0xFF) return;
  484. int dpx = dPosA[doa].x;
  485. int dpy = dPosA[doa].y;
  486. int dgx = dSizeA[doa].x;
  487. int dgy = dSizeA[doa].y;
  488. x += drawOff[doa].x;
  489. y += drawOff[doa].y;
  490. if (x + b < dpx || y + h < dpy || x >= dgx || y >= dgy) return;
  491. if (x < dpx)
  492. {
  493. b -= dpx - x;
  494. x = dpx;
  495. }
  496. if (y < dpy)
  497. {
  498. h -= dpy - y;
  499. y = dpy;
  500. }
  501. b = (x + b) >= dgx ? (dgx - x) : b;
  502. h = (y + h) >= dgy ? (dgy - y) : h;
  503. if (alpha[alphaCount])
  504. {
  505. unsigned char* cf = (unsigned char*)&ff;
  506. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  507. * (cf[3] - alpha[alphaCount]));
  508. }
  509. int* pixel = fc + y * size.x + x;
  510. int* rowEnd = pixel + b;
  511. if (alpha3D)
  512. {
  513. for (int i = 0; i < h; pixel += size.x - b, ++i, rowEnd += size.x)
  514. {
  515. for (; pixel < rowEnd; ++pixel)
  516. {
  517. alphaPixelP3D(*pixel, ff);
  518. }
  519. }
  520. }
  521. else
  522. {
  523. for (int i = 0; i < h; pixel += size.x - b, ++i, rowEnd += size.x)
  524. {
  525. for (; pixel < rowEnd; ++pixel)
  526. {
  527. alphaPixelP(*pixel, ff);
  528. }
  529. }
  530. }
  531. rend = 1;
  532. }
  533. void Image::alphaPixel2D(int i, int f)
  534. {
  535. if (!alpha[alphaCount])
  536. alphaPixelP(fc[i], f);
  537. else
  538. {
  539. unsigned char* cf = (unsigned char*)&f;
  540. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  541. * (cf[3] - alpha[alphaCount]));
  542. alphaPixelP(fc[i], f);
  543. rend = 1;
  544. }
  545. }
  546. void Image::alphaPixel3D(int i, int f)
  547. {
  548. if (!alpha[alphaCount])
  549. alphaPixelP3D(fc[i], f);
  550. else
  551. {
  552. unsigned char* cf = (unsigned char*)&f;
  553. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  554. * (cf[3] - alpha[alphaCount]));
  555. alphaPixelP3D(fc[i], f);
  556. rend = 1;
  557. }
  558. }
  559. void Image::alphaPixel2D(int x, int y, int f)
  560. {
  561. if (!alpha[alphaCount]) alphaPixelP(fc[x + y * size.x], f);
  562. if (alpha[alphaCount] < 0xFF)
  563. {
  564. unsigned char* cf = (unsigned char*)&f;
  565. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  566. * (cf[3] - alpha[alphaCount]));
  567. alphaPixelP(fc[x + y * size.x], f);
  568. rend = 1;
  569. }
  570. }
  571. void Image::alphaPixel3D(int x, int y, int f)
  572. {
  573. if (!alpha[alphaCount]) alphaPixelP3D(fc[x + y * size.x], f);
  574. if (alpha[alphaCount] < 0xFF)
  575. {
  576. unsigned char* cf = (unsigned char*)&f;
  577. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  578. * (cf[3] - alpha[alphaCount]));
  579. alphaPixelP3D(fc[x + y * size.x], f);
  580. rend = 1;
  581. }
  582. }
  583. void Image::alphaPixelDP2D(int x, int y, int f)
  584. {
  585. if (alpha[alphaCount] == 0xFF) return;
  586. int dpx = dPosA[doa].x;
  587. int dpy = dPosA[doa].y;
  588. int dgx = dSizeA[doa].x;
  589. int dgy = dSizeA[doa].y;
  590. x += drawOff[doa].x;
  591. y += drawOff[doa].y;
  592. if (x < dpx || y < dpy || x >= dgx || y >= dgy) return;
  593. if (alpha[alphaCount])
  594. {
  595. unsigned char* cf = (unsigned char*)&f;
  596. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  597. * (cf[3] - alpha[alphaCount]));
  598. }
  599. alphaPixelP(fc[x + y * size.x], f);
  600. rend = 1;
  601. }
  602. void Image::alphaPixelDP3D(int x, int y, int f)
  603. {
  604. if (alpha[alphaCount] == 0xFF) return;
  605. int dpx = dPosA[doa].x;
  606. int dpy = dPosA[doa].y;
  607. int dgx = dSizeA[doa].x;
  608. int dgy = dSizeA[doa].y;
  609. x += drawOff[doa].x;
  610. y += drawOff[doa].y;
  611. if (x < dpx || y < dpy || x >= dgx || y >= dgy) return;
  612. if (alpha[alphaCount])
  613. {
  614. unsigned char* cf = (unsigned char*)&f;
  615. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  616. * (cf[3] - alpha[alphaCount]));
  617. }
  618. alphaPixelP3D(fc[x + y * size.x], f);
  619. rend = 1;
  620. }
  621. void Image::alphaPixelDP2D(int i, int f)
  622. {
  623. int x = i % size.x;
  624. int y = i / size.x;
  625. alphaPixelDP2D(x, y, f);
  626. rend = 1;
  627. }
  628. void Image::alphaPixelDP3D(int i, int f)
  629. {
  630. int x = i % size.x;
  631. int y = i / size.x;
  632. alphaPixelDP3D(x, y, f);
  633. rend = 1;
  634. }
  635. void Image::setPixelDP(int x, int y, int f)
  636. {
  637. if (alpha[alphaCount] == 0xFF) return;
  638. if (alpha[alphaCount])
  639. {
  640. if (alpha3D)
  641. alphaPixelDP3D(x, y, f);
  642. else
  643. alphaPixelDP2D(x, y, f);
  644. return;
  645. }
  646. int dpx = dPosA[doa].x;
  647. int dpy = dPosA[doa].y;
  648. int dgx = dSizeA[doa].x;
  649. int dgy = dSizeA[doa].y;
  650. x += drawOff[doa].x;
  651. y += drawOff[doa].y;
  652. if (x < dpx || y < dpy || x >= dgx || y >= dgy) return;
  653. fc[x + y * size.x] = f;
  654. rend = 1;
  655. }
  656. void Image::setPixelDP(int i, int f)
  657. {
  658. int x = i % size.x;
  659. int y = i / size.x;
  660. setPixelDP(x, y, f);
  661. rend = 1;
  662. }
  663. void Image::drawLineH(int x, int y, int len, int f) // draws a horizontal line
  664. {
  665. if (alpha[alphaCount] == 0xFF) return;
  666. if (alpha[alphaCount])
  667. {
  668. drawLineHAlpha(x, y, len, f);
  669. return;
  670. }
  671. int dpx = dPosA[doa].x;
  672. int dpy = dPosA[doa].y;
  673. int dgx = dSizeA[doa].x;
  674. int dgy = dSizeA[doa].y;
  675. x += drawOff[doa].x;
  676. y += drawOff[doa].y;
  677. if (y < dpy || y >= dgy) return;
  678. if (x < dpx)
  679. {
  680. len -= dpx - x;
  681. if (len <= 0) return;
  682. x = dpx;
  683. }
  684. if (x + len >= dgx)
  685. {
  686. len -= x - dgx + len;
  687. if (len <= 0) return;
  688. }
  689. int br = size.x;
  690. int* fc = this->fc + x + y * br;
  691. int pval = len < 0 ? -1 : 1;
  692. len = len > 0 ? len : -len;
  693. for (int i = 0; i < len; ++i, fc += pval)
  694. *fc = f;
  695. rend = 1;
  696. }
  697. void Image::drawLineV(int x, int y, int len, int f) // draws a vertical line
  698. {
  699. if (alpha[alphaCount] == 0xFF) return;
  700. if (alpha[alphaCount])
  701. {
  702. drawLineVAlpha(x, y, len, f);
  703. return;
  704. }
  705. int dpx = dPosA[doa].x;
  706. int dpy = dPosA[doa].y;
  707. int dgx = dSizeA[doa].x;
  708. int dgy = dSizeA[doa].y;
  709. x += drawOff[doa].x;
  710. y += drawOff[doa].y;
  711. if (x < dpx || x >= dgx) return;
  712. if (y < dpy)
  713. {
  714. len -= dpy - y;
  715. if (len <= 0) return;
  716. y = dpy;
  717. }
  718. if (y + len >= dgy)
  719. {
  720. len -= y - dgy + len;
  721. if (len < 0) return;
  722. }
  723. int br = size.x;
  724. int* fc = this->fc + x + y * br;
  725. int pval = len < 0 ? -br : br;
  726. len = len > 0 ? len : -len;
  727. for (int i = 0; i < len; ++i, fc += pval)
  728. *fc = f;
  729. rend = 1;
  730. }
  731. void Image::drawLineHAlpha(
  732. int x, int y, int len, int f) // draws a horizontal line
  733. {
  734. if (alpha[alphaCount] == 0xFF) return;
  735. int dpx = dPosA[doa].x;
  736. int dpy = dPosA[doa].y;
  737. int dgx = dSizeA[doa].x;
  738. int dgy = dSizeA[doa].y;
  739. x += drawOff[doa].x;
  740. y += drawOff[doa].y;
  741. if (y < dpy || y >= dgy) return;
  742. if (x < dpx)
  743. {
  744. len -= dpx - x;
  745. if (len <= 0) return;
  746. x = dpx;
  747. }
  748. if (x + len >= dgx)
  749. {
  750. len -= x - dgx + len;
  751. if (len <= 0) return;
  752. }
  753. int br = size.x;
  754. int pval = len < 0 ? -1 : 1;
  755. len = len > 0 ? len : -len;
  756. int end = 0;
  757. if (alpha[alphaCount])
  758. {
  759. unsigned char* cf = (unsigned char*)&f;
  760. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  761. * (cf[3] - alpha[alphaCount]));
  762. }
  763. if (alpha3D)
  764. {
  765. for (int i = x + y * br; end < len; ++end, i += pval)
  766. {
  767. alphaPixelP3D(fc[i], f);
  768. }
  769. }
  770. else
  771. {
  772. for (int i = x + y * br; end < len; ++end, i += pval)
  773. {
  774. alphaPixelP(fc[i], f);
  775. }
  776. }
  777. rend = 1;
  778. }
  779. void Image::drawLineVAlpha(
  780. int x, int y, int len, int f) // draws a vertical line
  781. {
  782. if (alpha[alphaCount] == 0xFF) return;
  783. int dpx = dPosA[doa].x;
  784. int dpy = dPosA[doa].y;
  785. int dgx = dSizeA[doa].x;
  786. int dgy = dSizeA[doa].y;
  787. x += drawOff[doa].x;
  788. y += drawOff[doa].y;
  789. if (x < dpx || x >= dgx) return;
  790. if (y < dpy)
  791. {
  792. len -= dpy - y;
  793. if (len <= 0) return;
  794. y = dpy;
  795. }
  796. if (y + len >= dgy)
  797. {
  798. len -= y - dgy + len;
  799. if (len < 0) return;
  800. }
  801. int br = size.x;
  802. int pval = len < 0 ? -br : br;
  803. len = len > 0 ? len : -len;
  804. int end = 0;
  805. if (alpha[alphaCount])
  806. {
  807. unsigned char* cf = (unsigned char*)&f;
  808. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  809. * (cf[3] - alpha[alphaCount]));
  810. }
  811. if (alpha3D)
  812. {
  813. for (int i = x + y * br; end < len; ++end, i += pval)
  814. {
  815. alphaPixelP3D(fc[i], f);
  816. }
  817. }
  818. else
  819. {
  820. for (int i = x + y * br; end < len; ++end, i += pval)
  821. {
  822. alphaPixelP(fc[i], f);
  823. }
  824. }
  825. rend = 1;
  826. }
  827. void Image::drawLineBordered(Point a, Point b, int bc, int fc)
  828. {
  829. if (alpha[alphaCount] == 0xFF) return;
  830. if (alpha[alphaCount])
  831. {
  832. drawLineBorderedAlpha(a, b, bc, fc);
  833. return;
  834. }
  835. a += drawOff[doa];
  836. b += drawOff[doa];
  837. char outCode1 = getOutCode(a);
  838. char outCode2 = getOutCode(b);
  839. bool ok = 0;
  840. while (1)
  841. {
  842. int xMax = dSizeA[doa].x - 1;
  843. int yMax = dSizeA[doa].y - 1;
  844. if (!(outCode1 | outCode2))
  845. {
  846. ok = 1;
  847. break;
  848. }
  849. else if (outCode1 & outCode2)
  850. break;
  851. else
  852. {
  853. int x = 0, y = 0;
  854. char outCodeOut = outCode1 ? outCode1 : outCode2;
  855. if (outCodeOut & 8)
  856. {
  857. x = (int)(a.x + (b.x - a.x) * (yMax - a.y) / (b.y - a.y) + 0.5);
  858. y = yMax;
  859. }
  860. else if (outCodeOut & 4)
  861. {
  862. x = (int)(a.x + (b.x - a.x) * (dPosA[doa].y - a.y) / (b.y - a.y)
  863. + 0.5);
  864. y = dPosA[doa].y;
  865. }
  866. else if (outCodeOut & 2)
  867. {
  868. y = (int)(a.y + (b.y - a.y) * (xMax - a.x) / (b.x - a.x) + 0.5);
  869. x = xMax;
  870. }
  871. else if (outCodeOut & 1)
  872. {
  873. y = (int)(a.y + (b.y - a.y) * (dPosA[doa].x - a.x) / (b.x - a.x)
  874. + 0.5);
  875. x = dPosA[doa].x;
  876. }
  877. if (outCodeOut == outCode1)
  878. {
  879. a.x = x;
  880. a.y = y;
  881. outCode1 = getOutCode(a);
  882. }
  883. else
  884. {
  885. b.x = x;
  886. b.y = y;
  887. outCode2 = getOutCode(b);
  888. }
  889. }
  890. }
  891. if (ok)
  892. {
  893. int xlen = b.x - a.x, axlen = abs(xlen);
  894. int ylen = b.y - a.y, aylen = abs(ylen);
  895. double xf = (double)xlen / (aylen ? aylen : 1);
  896. double yf = (double)ylen / (axlen ? axlen : 1);
  897. if (axlen > aylen)
  898. xf = xf < 0 ? -1 : 1;
  899. else
  900. yf = yf < 0 ? -1 : 1;
  901. double x = (double)a.x, y = (double)a.y;
  902. int maxP = (int)(sqrt((float)(xlen * xlen + ylen * ylen)) + 0.5);
  903. int count = 0;
  904. int maxPixel = size.x * size.y;
  905. while (
  906. !((int)(x + 0.5) == b.x && (int)(y + 0.5) == b.y) && count < maxP)
  907. {
  908. ++count;
  909. this->fc[(int)((int)(x + 0.5) + (int)(y + 0.5) * size.x)] = fc;
  910. if ((int)((int)(x - 0.5) + (int)(y + 0.5) * size.x) < maxPixel
  911. && this->fc[(int)((int)(x - 0.5) + (int)(y + 0.5) * size.x)]
  912. != fc)
  913. this->fc[(int)((int)(x - 0.5) + (int)(y + 0.5) * size.x)] = bc;
  914. if ((int)((int)(x + 1.5) + (int)(y + 0.5) * size.x) < maxPixel
  915. && this->fc[(int)((int)(x + 1.5) + (int)(y + 0.5) * size.x)]
  916. != fc)
  917. this->fc[(int)((int)(x + 1.5) + (int)(y + 0.5) * size.x)] = bc;
  918. if ((int)((int)(x + 0.5) + (int)(y - 0.5) * size.x) < maxPixel
  919. && this->fc[(int)((int)(x + 0.5) + (int)(y - 0.5) * size.x)]
  920. != fc)
  921. this->fc[(int)((int)(x + 0.5) + (int)(y - 0.5) * size.x)] = bc;
  922. if ((int)((int)(x + 0.5) + (int)(y + 1.5) * size.x) < maxPixel
  923. && this->fc[(int)((int)(x + 0.5) + (int)(y + 1.5) * size.x)]
  924. != fc)
  925. this->fc[(int)((int)(x + 0.5) + (int)(y + 1.5) * size.x)] = bc;
  926. x += xf, y += yf;
  927. }
  928. rend = 1;
  929. }
  930. }
  931. void Image::drawLineBorderedAlpha(Point a, Point b, int bc, int fc)
  932. {
  933. if (alpha[alphaCount] == 0xFF) return;
  934. a += drawOff[doa];
  935. b += drawOff[doa];
  936. char outCode1 = getOutCode(a);
  937. char outCode2 = getOutCode(b);
  938. bool ok = 0;
  939. while (1)
  940. {
  941. int xMax = dSizeA[doa].x - 1;
  942. int yMax = dSizeA[doa].y - 1;
  943. if (!(outCode1 | outCode2))
  944. {
  945. ok = 1;
  946. break;
  947. }
  948. else if (outCode1 & outCode2)
  949. break;
  950. else
  951. {
  952. int x = 0, y = 0;
  953. char outCodeOut = outCode1 ? outCode1 : outCode2;
  954. if (outCodeOut & 8)
  955. {
  956. x = (int)(a.x + (b.x - a.x) * (yMax - a.y) / (b.y - a.y) + 0.5);
  957. y = yMax;
  958. }
  959. else if (outCodeOut & 4)
  960. {
  961. x = (int)(a.x + (b.x - a.x) * (dPosA[doa].y - a.y) / (b.y - a.y)
  962. + 0.5);
  963. y = dPosA[doa].y;
  964. }
  965. else if (outCodeOut & 2)
  966. {
  967. y = (int)(a.y + (b.y - a.y) * (xMax - a.x) / (b.x - a.x) + 0.5);
  968. x = xMax;
  969. }
  970. else if (outCodeOut & 1)
  971. {
  972. y = (int)(a.y + (b.y - a.y) * (dPosA[doa].x - a.x) / (b.x - a.x)
  973. + 0.5);
  974. x = dPosA[doa].x;
  975. }
  976. if (outCodeOut == outCode1)
  977. {
  978. a.x = x;
  979. a.y = y;
  980. outCode1 = getOutCode(a);
  981. }
  982. else
  983. {
  984. b.x = x;
  985. b.y = y;
  986. outCode2 = getOutCode(b);
  987. }
  988. }
  989. }
  990. if (ok)
  991. {
  992. int xlen = b.x - a.x, axlen = abs(xlen);
  993. int ylen = b.y - a.y, aylen = abs(ylen);
  994. double xf = (double)xlen / (aylen ? aylen : 1);
  995. double yf = (double)ylen / (axlen ? axlen : 1);
  996. if (axlen > aylen)
  997. xf = xf < 0 ? -1 : 1;
  998. else
  999. yf = yf < 0 ? -1 : 1;
  1000. double x = (double)a.x, y = (double)a.y;
  1001. if (alpha[alphaCount])
  1002. {
  1003. unsigned char* cf = (unsigned char*)&fc;
  1004. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  1005. * (cf[3] - alpha[alphaCount]));
  1006. }
  1007. int maxP = (int)(sqrt((float)(xlen * xlen + ylen * ylen)) + 0.5);
  1008. int count = 0;
  1009. int maxPixel = size.x * size.y;
  1010. if (alpha3D)
  1011. {
  1012. while (!((int)(x + 0.5) == b.x && (int)(y + 0.5) == b.y)
  1013. && count < maxP)
  1014. {
  1015. ++count;
  1016. if ((int)((int)(x - 0.5) + (int)(y + 0.5) * size.x) < maxPixel)
  1017. {
  1018. int& pixel
  1019. = this->fc[(int)(x - 0.5) + (int)(y + 0.5) * size.x];
  1020. alphaPixelP3D(pixel, bc);
  1021. }
  1022. if ((int)((int)(x + 1.5) + (int)(y + 0.5) * size.x) < maxPixel)
  1023. {
  1024. int& pixel
  1025. = this->fc[(int)(x + 1.5) + (int)(y + 0.5) * size.x];
  1026. alphaPixelP3D(pixel, bc);
  1027. }
  1028. if ((int)((int)(x + 0.5) + (int)(y - 0.5) * size.x) < maxPixel)
  1029. {
  1030. int& pixel
  1031. = this->fc[(int)(x + 0.5) + (int)(y - 0.5) * size.x];
  1032. alphaPixelP3D(pixel, bc);
  1033. }
  1034. if ((int)((int)(x + 0.5) + (int)(y + 1.5) * size.x) < maxPixel)
  1035. {
  1036. int& pixel
  1037. = this->fc[(int)(x + 0.5) + (int)(y + 1.5) * size.x];
  1038. alphaPixelP3D(pixel, bc);
  1039. }
  1040. x += xf, y += yf;
  1041. }
  1042. count = 0;
  1043. while (!((int)(x + 0.5) == b.x && (int)(y + 0.5) == b.y)
  1044. && count < maxP)
  1045. {
  1046. ++count;
  1047. int& pixel = this->fc[(int)(x + 0.5) + (int)(y + 0.5) * size.x];
  1048. alphaPixelP3D(pixel, fc);
  1049. x += xf, y += yf;
  1050. }
  1051. }
  1052. else
  1053. {
  1054. while (!((int)(x + 0.5) == b.x && (int)(y + 0.5) == b.y)
  1055. && count < maxP)
  1056. {
  1057. ++count;
  1058. if ((int)((int)(x - 0.5) + (int)(y + 0.5) * size.x) < maxPixel)
  1059. {
  1060. int& pixel
  1061. = this->fc[(int)(x - 0.5) + (int)(y + 0.5) * size.x];
  1062. alphaPixelP(pixel, bc);
  1063. }
  1064. if ((int)((int)(x + 1.5) + (int)(y + 0.5) * size.x) < maxPixel)
  1065. {
  1066. int& pixel
  1067. = this->fc[(int)(x + 1.5) + (int)(y + 0.5) * size.x];
  1068. alphaPixelP(pixel, bc);
  1069. }
  1070. if ((int)((int)(x + 0.5) + (int)(y - 0.5) * size.x) < maxPixel)
  1071. {
  1072. int& pixel
  1073. = this->fc[(int)(x + 0.5) + (int)(y - 0.5) * size.x];
  1074. alphaPixelP(pixel, bc);
  1075. }
  1076. if ((int)((int)(x + 0.5) + (int)(y + 1.5) * size.x) < maxPixel)
  1077. {
  1078. int& pixel
  1079. = this->fc[(int)(x + 0.5) + (int)(y + 1.5) * size.x];
  1080. alphaPixelP(pixel, bc);
  1081. }
  1082. x += xf, y += yf;
  1083. }
  1084. count = 0;
  1085. while (!((int)(x + 0.5) == b.x && (int)(y + 0.5) == b.y)
  1086. && count < maxP)
  1087. {
  1088. ++count;
  1089. int& pixel = this->fc[(int)(x + 0.5) + (int)(y + 0.5) * size.x];
  1090. alphaPixelP(pixel, fc);
  1091. x += xf, y += yf;
  1092. }
  1093. }
  1094. rend = 1;
  1095. }
  1096. }
  1097. void Image::drawLine(Point a,
  1098. Point b,
  1099. int fc) // draws a line from Point(x1, y1) to Point(x2, y2)
  1100. {
  1101. if (alpha[alphaCount] == 0xFF) return;
  1102. if (alpha[alphaCount])
  1103. {
  1104. drawLineAlpha(a, b, fc);
  1105. return;
  1106. }
  1107. a += drawOff[doa];
  1108. b += drawOff[doa];
  1109. char outCode1 = getOutCode(a);
  1110. char outCode2 = getOutCode(b);
  1111. bool ok = 0;
  1112. while (1)
  1113. {
  1114. int xMax = dSizeA[doa].x - 1;
  1115. int yMax = dSizeA[doa].y - 1;
  1116. if (!(outCode1 | outCode2))
  1117. {
  1118. ok = 1;
  1119. break;
  1120. }
  1121. else if (outCode1 & outCode2)
  1122. break;
  1123. else
  1124. {
  1125. int x = 0, y = 0;
  1126. char outCodeOut = outCode1 ? outCode1 : outCode2;
  1127. if (outCodeOut & 8)
  1128. {
  1129. x = (int)(a.x + (b.x - a.x) * (yMax - a.y) / (b.y - a.y) + 0.5);
  1130. y = yMax;
  1131. }
  1132. else if (outCodeOut & 4)
  1133. {
  1134. x = (int)(a.x + (b.x - a.x) * (dPosA[doa].y - a.y) / (b.y - a.y)
  1135. + 0.5);
  1136. y = dPosA[doa].y;
  1137. }
  1138. else if (outCodeOut & 2)
  1139. {
  1140. y = (int)(a.y + (b.y - a.y) * (xMax - a.x) / (b.x - a.x) + 0.5);
  1141. x = xMax;
  1142. }
  1143. else if (outCodeOut & 1)
  1144. {
  1145. y = (int)(a.y + (b.y - a.y) * (dPosA[doa].x - a.x) / (b.x - a.x)
  1146. + 0.5);
  1147. x = dPosA[doa].x;
  1148. }
  1149. if (outCodeOut == outCode1)
  1150. {
  1151. a.x = x;
  1152. a.y = y;
  1153. outCode1 = getOutCode(a);
  1154. }
  1155. else
  1156. {
  1157. b.x = x;
  1158. b.y = y;
  1159. outCode2 = getOutCode(b);
  1160. }
  1161. }
  1162. }
  1163. if (ok)
  1164. {
  1165. int xlen = b.x - a.x, axlen = abs(xlen);
  1166. int ylen = b.y - a.y, aylen = abs(ylen);
  1167. double xf = (double)xlen / (aylen ? aylen : 1);
  1168. double yf = (double)ylen / (axlen ? axlen : 1);
  1169. if (axlen > aylen)
  1170. xf = xf < 0 ? -1 : 1;
  1171. else
  1172. yf = yf < 0 ? -1 : 1;
  1173. double x = (double)a.x, y = (double)a.y;
  1174. int maxP = (int)(sqrt((float)(xlen * xlen + ylen * ylen)) + 0.5);
  1175. int count = 0;
  1176. while (
  1177. !((int)(x + 0.5) == b.x && (int)(y + 0.5) == b.y) && count < maxP)
  1178. {
  1179. ++count;
  1180. this->fc[(int)((int)(x + 0.5) + (int)(y + 0.5) * size.x)] = fc;
  1181. x += xf, y += yf;
  1182. }
  1183. this->fc[(int)((int)(x + 0.5) + (int)(y + 0.5) * size.x)] = fc;
  1184. rend = 1;
  1185. }
  1186. }
  1187. void Image::drawLineAlpha(Point a, Point b, int fc)
  1188. {
  1189. if (alpha[alphaCount] == 0xFF) return;
  1190. a += drawOff[doa];
  1191. b += drawOff[doa];
  1192. char outCode1 = getOutCode(a);
  1193. char outCode2 = getOutCode(b);
  1194. bool ok = 0;
  1195. while (1)
  1196. {
  1197. int xMax = dSizeA[doa].x - 1;
  1198. int yMax = dSizeA[doa].y - 1;
  1199. if (!(outCode1 | outCode2))
  1200. {
  1201. ok = 1;
  1202. break;
  1203. }
  1204. else if (outCode1 & outCode2)
  1205. break;
  1206. else
  1207. {
  1208. int x = 0, y = 0;
  1209. char outCodeOut = outCode1 ? outCode1 : outCode2;
  1210. if (outCodeOut & 8)
  1211. {
  1212. x = (int)(a.x + (b.x - a.x) * (yMax - a.y) / (b.y - a.y) + 0.5);
  1213. y = yMax;
  1214. }
  1215. else if (outCodeOut & 4)
  1216. {
  1217. x = (int)(a.x + (b.x - a.x) * (dPosA[doa].y - a.y) / (b.y - a.y)
  1218. + 0.5);
  1219. y = dPosA[doa].y;
  1220. }
  1221. else if (outCodeOut & 2)
  1222. {
  1223. y = (int)(a.y + (b.y - a.y) * (xMax - a.x) / (b.x - a.x) + 0.5);
  1224. x = xMax;
  1225. }
  1226. else if (outCodeOut & 1)
  1227. {
  1228. y = (int)(a.y + (b.y - a.y) * (dPosA[doa].x - a.x) / (b.x - a.x)
  1229. + 0.5);
  1230. x = dPosA[doa].x;
  1231. }
  1232. if (outCodeOut == outCode1)
  1233. {
  1234. a.x = x;
  1235. a.y = y;
  1236. outCode1 = getOutCode(a);
  1237. }
  1238. else
  1239. {
  1240. b.x = x;
  1241. b.y = y;
  1242. outCode2 = getOutCode(b);
  1243. }
  1244. }
  1245. }
  1246. if (ok)
  1247. {
  1248. int xlen = b.x - a.x, axlen = abs(xlen);
  1249. int ylen = b.y - a.y, aylen = abs(ylen);
  1250. double xf = (double)xlen / (aylen ? aylen : 1);
  1251. double yf = (double)ylen / (axlen ? axlen : 1);
  1252. if (axlen > aylen)
  1253. xf = xf < 0 ? -1 : 1;
  1254. else
  1255. yf = yf < 0 ? -1 : 1;
  1256. double x = (double)a.x, y = (double)a.y;
  1257. if (alpha[alphaCount])
  1258. {
  1259. unsigned char* cf = (unsigned char*)&fc;
  1260. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  1261. * (cf[3] - alpha[alphaCount]));
  1262. }
  1263. int maxP = (int)(sqrt((float)(xlen * xlen + ylen * ylen)) + 0.5);
  1264. int count = 0;
  1265. if (alpha3D)
  1266. {
  1267. while (!((int)(x + 0.5) == b.x && (int)(y + 0.5) == b.y)
  1268. && count < maxP)
  1269. {
  1270. ++count;
  1271. int& pixel = this->fc[(int)(x + 0.5) + (int)(y + 0.5) * size.x];
  1272. alphaPixelP3D(pixel, fc);
  1273. x += xf, y += yf;
  1274. }
  1275. int& pixel = this->fc[(int)(x + 0.5) + (int)(y + 0.5) * size.x];
  1276. alphaPixelP3D(pixel, fc);
  1277. }
  1278. else
  1279. {
  1280. while (!((int)(x + 0.5) == b.x && (int)(y + 0.5) == b.y)
  1281. && count < maxP)
  1282. {
  1283. ++count;
  1284. int& pixel = this->fc[(int)(x + 0.5) + (int)(y + 0.5) * size.x];
  1285. alphaPixelP(pixel, fc);
  1286. x += xf, y += yf;
  1287. }
  1288. int& pixel = this->fc[(int)(x + 0.5) + (int)(y + 0.5) * size.x];
  1289. alphaPixelP(pixel, fc);
  1290. }
  1291. rend = 1;
  1292. }
  1293. }
  1294. void Image::fillCircle(int xOff,
  1295. int yOff,
  1296. int r,
  1297. int fc) // fills a circle around Point(xOff, yOff) with radius r
  1298. {
  1299. if (alpha[alphaCount] == 0xFF) return;
  1300. for (int i = r; i > 0; i--)
  1301. drawCircle(xOff, yOff, i, fc);
  1302. }
  1303. void Image::drawCircle(int xOff,
  1304. int yOff,
  1305. int r,
  1306. int fc) // draws a circle around Point(xOff, yOff) with radius r
  1307. {
  1308. if (alpha[alphaCount] == 0xFF) return;
  1309. if (alpha[alphaCount])
  1310. {
  1311. drawCircleAlpha(xOff, yOff, r, fc);
  1312. return;
  1313. }
  1314. int dpx = dPosA[doa].x;
  1315. int dpy = dPosA[doa].y;
  1316. int dgx = dSizeA[doa].x;
  1317. int dgy = dSizeA[doa].y;
  1318. xOff += drawOff[doa].x;
  1319. yOff += drawOff[doa].y;
  1320. if (xOff + r < dpx || xOff - r >= dgx || yOff + r < dpy || yOff - r >= dgy)
  1321. return;
  1322. for (int a = 0; a < r; ++a)
  1323. {
  1324. int b = (int)(sqrt((float)(long)(r * r - a * a)) + 0.5);
  1325. if (xOff + a < dgx && xOff + a > dpx && yOff + b < dgy
  1326. && yOff + b > dpy)
  1327. this->fc[xOff + a + (yOff + b) * size.x] = fc;
  1328. if (xOff - a < dgx && xOff - a > dpx && yOff + b < dgy
  1329. && yOff + b > dpy)
  1330. this->fc[xOff - a + (yOff + b) * size.x] = fc;
  1331. if (xOff + a < dgx && xOff + a > dpx && yOff - b < dgy
  1332. && yOff - b > dpy)
  1333. this->fc[xOff + a + (yOff - b) * size.x] = fc;
  1334. if (xOff - a < dgx && xOff - a > dpx && yOff - b < dgy
  1335. && yOff - b > dpy)
  1336. this->fc[xOff - a + (yOff - b) * size.x] = fc;
  1337. if (xOff + b < dgx && xOff + b > dpx && yOff + a < dgy
  1338. && yOff + a > dpy)
  1339. this->fc[xOff + b + (yOff + a) * size.x] = fc;
  1340. if (xOff - b < dgx && xOff - b > dpx && yOff + a < dgy
  1341. && yOff + a > dpy)
  1342. this->fc[xOff - b + (yOff + a) * size.x] = fc;
  1343. if (xOff + b < dgx && xOff + b > dpx && yOff - a < dgy
  1344. && yOff - a > dpy)
  1345. this->fc[xOff + b + (yOff - a) * size.x] = fc;
  1346. if (xOff - b < dgx && xOff - b > dpx && yOff - a < dgy
  1347. && yOff - a > dpy)
  1348. this->fc[xOff - b + (yOff - a) * size.x] = fc;
  1349. }
  1350. rend = 1;
  1351. }
  1352. void Image::drawCircleAlpha(int xOff, int yOff, int r, int fc)
  1353. {
  1354. if (alpha[alphaCount] == 0xFF) return;
  1355. int dpx = dPosA[doa].x;
  1356. int dpy = dPosA[doa].y;
  1357. int dgx = dSizeA[doa].x;
  1358. int dgy = dSizeA[doa].y;
  1359. xOff += drawOff[doa].x;
  1360. yOff += drawOff[doa].y;
  1361. if (xOff + r < dpx || xOff - r >= dgx || yOff + r < dpy || yOff - r >= dgy)
  1362. return;
  1363. if (alpha[alphaCount] < 0xFF)
  1364. {
  1365. unsigned char* cf = (unsigned char*)&fc;
  1366. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  1367. * (cf[3] - alpha[alphaCount]));
  1368. }
  1369. if (alpha3D)
  1370. {
  1371. for (int a = 0; a < r; ++a)
  1372. {
  1373. int b = (int)(sqrt((float)(long)(r * r - a * a)) + 0.5);
  1374. int* pixel = 0;
  1375. if (xOff + a < dgx && xOff + a > dpx && yOff + b < dgy
  1376. && yOff + b > dpy)
  1377. {
  1378. pixel = &this->fc[xOff + a + (yOff + b) * size.x];
  1379. alphaPixelP3D(*pixel, fc);
  1380. }
  1381. if (xOff - a < dgx && xOff - a > dpx && yOff + b < dgy
  1382. && yOff + b > dpy)
  1383. {
  1384. pixel = &this->fc[xOff - a + (yOff + b) * size.x];
  1385. alphaPixelP3D(*pixel, fc);
  1386. }
  1387. if (xOff + a < dgx && xOff + a > dpx && yOff - b < dgy
  1388. && yOff - b > dpy)
  1389. {
  1390. pixel = &this->fc[xOff + a + (yOff - b) * size.x];
  1391. alphaPixelP3D(*pixel, fc);
  1392. }
  1393. if (xOff - a < dgx && xOff - a > dpx && yOff - b < dgy
  1394. && yOff - b > dpy)
  1395. {
  1396. pixel = &this->fc[xOff - a + (yOff - b) * size.x];
  1397. alphaPixelP3D(*pixel, fc);
  1398. }
  1399. if (xOff + b < dgx && xOff + b > dpx && yOff + a < dgy
  1400. && yOff + a > dpy)
  1401. {
  1402. pixel = &this->fc[xOff + b + (yOff + a) * size.x];
  1403. alphaPixelP3D(*pixel, fc);
  1404. }
  1405. if (xOff - b < dgx && xOff - b > dpx && yOff + a < dgy
  1406. && yOff + a > dpy)
  1407. {
  1408. pixel = &this->fc[xOff - b + (yOff + a) * size.x];
  1409. alphaPixelP3D(*pixel, fc);
  1410. }
  1411. if (xOff + b < dgx && xOff + b > dpx && yOff - a < dgy
  1412. && yOff - a > dpy)
  1413. {
  1414. pixel = &this->fc[xOff + b + (yOff - a) * size.x];
  1415. alphaPixelP3D(*pixel, fc);
  1416. }
  1417. if (xOff - b < dgx && xOff - b > dpx && yOff - a < dgy
  1418. && yOff - a > dpy)
  1419. {
  1420. pixel = &this->fc[xOff - b + (yOff - a) * size.x];
  1421. alphaPixelP3D(*pixel, fc);
  1422. }
  1423. }
  1424. }
  1425. else
  1426. {
  1427. for (int a = 0; a < r; ++a)
  1428. {
  1429. int b = (int)(sqrt((float)(long)(r * r - a * a)) + 0.5);
  1430. int* pixel = 0;
  1431. if (xOff + a < dgx && xOff + a > dpx && yOff + b < dgy
  1432. && yOff + b > dpy)
  1433. {
  1434. pixel = &this->fc[xOff + a + (yOff + b) * size.x];
  1435. alphaPixelP(*pixel, fc);
  1436. }
  1437. if (xOff - a < dgx && xOff - a > dpx && yOff + b < dgy
  1438. && yOff + b > dpy)
  1439. {
  1440. pixel = &this->fc[xOff - a + (yOff + b) * size.x];
  1441. alphaPixelP(*pixel, fc);
  1442. }
  1443. if (xOff + a < dgx && xOff + a > dpx && yOff - b < dgy
  1444. && yOff - b > dpy)
  1445. {
  1446. pixel = &this->fc[xOff + a + (yOff - b) * size.x];
  1447. alphaPixelP(*pixel, fc);
  1448. }
  1449. if (xOff - a < dgx && xOff - a > dpx && yOff - b < dgy
  1450. && yOff - b > dpy)
  1451. {
  1452. pixel = &this->fc[xOff - a + (yOff - b) * size.x];
  1453. alphaPixelP(*pixel, fc);
  1454. }
  1455. if (xOff + b < dgx && xOff + b > dpx && yOff + a < dgy
  1456. && yOff + a > dpy)
  1457. {
  1458. pixel = &this->fc[xOff + b + (yOff + a) * size.x];
  1459. alphaPixelP(*pixel, fc);
  1460. }
  1461. if (xOff - b < dgx && xOff - b > dpx && yOff + a < dgy
  1462. && yOff + a > dpy)
  1463. {
  1464. pixel = &this->fc[xOff - b + (yOff + a) * size.x];
  1465. alphaPixelP(*pixel, fc);
  1466. }
  1467. if (xOff + b < dgx && xOff + b > dpx && yOff - a < dgy
  1468. && yOff - a > dpy)
  1469. {
  1470. pixel = &this->fc[xOff + b + (yOff - a) * size.x];
  1471. alphaPixelP(*pixel, fc);
  1472. }
  1473. if (xOff - b < dgx && xOff - b > dpx && yOff - a < dgy
  1474. && yOff - a > dpy)
  1475. {
  1476. pixel = &this->fc[xOff - b + (yOff - a) * size.x];
  1477. alphaPixelP(*pixel, fc);
  1478. }
  1479. }
  1480. }
  1481. rend = 1;
  1482. }
  1483. void Image::drawImage(
  1484. int x, int y, int br, int hi, const Image& zImage) // draws zImage
  1485. {
  1486. if (alpha[alphaCount] == 0xFF) return;
  1487. if (alpha[alphaCount])
  1488. {
  1489. alphaImage(x, y, br, hi, zImage);
  1490. return;
  1491. }
  1492. int dpx = dPosA[doa].x;
  1493. int dpy = dPosA[doa].y;
  1494. int dgx = dSizeA[doa].x;
  1495. int dgy = dSizeA[doa].y;
  1496. x += drawOff[doa].x;
  1497. y += drawOff[doa].y;
  1498. if (x + br < dpx || y + hi < dpy || x >= dgx || y >= dgy) return;
  1499. br = minInt(br, zImage.getWidth());
  1500. hi = minInt(hi, zImage.getHeight());
  1501. int xst = maxInt(dpx - x, 0);
  1502. int yst = maxInt(dpy - y, 0);
  1503. int xst2 = maxInt(x, dpx);
  1504. int yst2 = maxInt(y, dpy);
  1505. dgx = minInt(x + br, dgx);
  1506. dgy = minInt(y + hi, dgy);
  1507. int bb = zImage.getWidth();
  1508. int* ff = zImage.getBuffer();
  1509. int xx, ygr, ygr2;
  1510. for (int yy = yst2; yy < dgy; ++yy)
  1511. {
  1512. ygr = yy * size.x;
  1513. ygr2 = (yy - yst2 + yst) * bb;
  1514. for (xx = xst2; xx < dgx; ++xx)
  1515. fc[xx + ygr] = ff[(xx - xst2 + xst) + ygr2];
  1516. }
  1517. rend = 1;
  1518. }
  1519. void Image::alphaImageAssoc(int x, int y, int br, int hi, const Image& zImage)
  1520. {
  1521. if (alpha[alphaCount] == 0xFF) return;
  1522. int dpx = dPosA[doa].x;
  1523. int dpy = dPosA[doa].y;
  1524. int dgx = dSizeA[doa].x;
  1525. int dgy = dSizeA[doa].y;
  1526. x += drawOff[doa].x;
  1527. y += drawOff[doa].y;
  1528. if (x + br < dpx || y + hi < dpy || x >= dgx || y >= dgy) return;
  1529. br = minInt(br, zImage.getWidth());
  1530. hi = minInt(hi, zImage.getHeight());
  1531. int xst = maxInt(dpx - x, 0);
  1532. int yst = maxInt(dpy - y, 0);
  1533. int xst2 = maxInt(x, dpx);
  1534. int yst2 = maxInt(y, dpy);
  1535. dgx = minInt(x + br, dgx);
  1536. dgy = minInt(y + hi, dgy);
  1537. int bb = zImage.getWidth();
  1538. int* ff = zImage.getBuffer();
  1539. if (!alpha[alphaCount])
  1540. {
  1541. int xx, ygr, ygr2;
  1542. for (int yy = yst2; yy < dgy; ++yy)
  1543. {
  1544. ygr = yy * size.x;
  1545. ygr2 = (yy - yst2 + yst) * bb;
  1546. for (xx = xst2; xx < dgx; ++xx)
  1547. alphaPixelAssozP(fc[xx + ygr], ff[(xx - xst2 + xst) + ygr2]);
  1548. }
  1549. }
  1550. else
  1551. {
  1552. int xx, ygr, ygr2;
  1553. for (int yy = yst2; yy < dgy; ++yy)
  1554. {
  1555. ygr = yy * size.x;
  1556. ygr2 = (yy - yst2 + yst) * bb;
  1557. for (xx = xst2; xx < dgx; ++xx)
  1558. {
  1559. int fc = ff[(xx - xst2 + xst) + ygr2];
  1560. unsigned char* cf = (unsigned char*)&fc;
  1561. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  1562. * (cf[3] - alpha[alphaCount]));
  1563. alphaPixelAssozP(this->fc[xx + ygr], fc);
  1564. }
  1565. }
  1566. }
  1567. rend = 1;
  1568. }
  1569. void Image::alphaImage(int x, int y, int br, int hi, const Image& zImage)
  1570. {
  1571. if (alpha[alphaCount] == 0xFF) return;
  1572. int dpx = dPosA[doa].x;
  1573. int dpy = dPosA[doa].y;
  1574. int dgx = dSizeA[doa].x;
  1575. int dgy = dSizeA[doa].y;
  1576. x += drawOff[doa].x;
  1577. y += drawOff[doa].y;
  1578. if (x + br < dpx || y + hi < dpy || x >= dgx || y >= dgy) return;
  1579. br = minInt(br, zImage.getWidth());
  1580. hi = minInt(hi, zImage.getHeight());
  1581. int xst = maxInt(dpx - x, 0);
  1582. int yst = maxInt(dpy - y, 0);
  1583. int xst2 = maxInt(x, dpx);
  1584. int yst2 = maxInt(y, dpy);
  1585. dgx = minInt(x + br, dgx);
  1586. dgy = minInt(y + hi, dgy);
  1587. int bb = zImage.getWidth();
  1588. int* ff = zImage.getBuffer();
  1589. if (!alpha[alphaCount])
  1590. {
  1591. int xx, ygr, ygr2;
  1592. if (alpha3D)
  1593. {
  1594. for (int yy = yst2; yy < dgy; ++yy)
  1595. {
  1596. ygr = yy * size.x;
  1597. ygr2 = (yy - yst2 + yst) * bb;
  1598. int fci = xst2 + ygr;
  1599. int ffi = xst + ygr2;
  1600. for (xx = xst2; xx < dgx; ++xx, ++fci, ++ffi)
  1601. alphaPixelP3D(fc[fci], ff[ffi]);
  1602. }
  1603. }
  1604. else
  1605. {
  1606. for (int yy = yst2; yy < dgy; ++yy)
  1607. {
  1608. ygr = yy * size.x;
  1609. ygr2 = (yy - yst2 + yst) * bb;
  1610. int fci = xst2 + ygr;
  1611. int ffi = xst + ygr2;
  1612. for (xx = xst2; xx < dgx; ++xx, ++fci, ++ffi)
  1613. alphaPixelP(fc[fci], ff[ffi]);
  1614. }
  1615. }
  1616. }
  1617. else
  1618. {
  1619. int xx, ygr, ygr2;
  1620. if (alpha3D)
  1621. {
  1622. for (int yy = yst2; yy < dgy; ++yy)
  1623. {
  1624. ygr = yy * size.x;
  1625. ygr2 = (yy - yst2 + yst) * bb;
  1626. for (xx = xst2; xx < dgx; ++xx)
  1627. {
  1628. int fc = ff[(xx - xst2 + xst) + ygr2];
  1629. unsigned char* cf = (unsigned char*)&fc;
  1630. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  1631. * (cf[3] - alpha[alphaCount]));
  1632. alphaPixelP3D(this->fc[xx + ygr], fc);
  1633. }
  1634. }
  1635. }
  1636. else
  1637. {
  1638. for (int yy = yst2; yy < dgy; ++yy)
  1639. {
  1640. ygr = yy * size.x;
  1641. ygr2 = (yy - yst2 + yst) * bb;
  1642. for (xx = xst2; xx < dgx; ++xx)
  1643. {
  1644. int fc = ff[(xx - xst2 + xst) + ygr2];
  1645. unsigned char* cf = (unsigned char*)&fc;
  1646. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  1647. * (cf[3] - alpha[alphaCount]));
  1648. alphaPixelP(this->fc[xx + ygr], fc);
  1649. }
  1650. }
  1651. }
  1652. }
  1653. rend = 1;
  1654. }
  1655. void Image::drawImage90(int x,
  1656. int y,
  1657. int br,
  1658. int hi,
  1659. const Image& zImage) // Draws an image rotated 90 degrees to the right
  1660. {
  1661. if (alpha[alphaCount] == 0xFF) return;
  1662. if (alpha[alphaCount])
  1663. {
  1664. alphaImage90(x, y, br, hi, zImage);
  1665. return;
  1666. }
  1667. int dpx = dPosA[doa].x;
  1668. int dpy = dPosA[doa].y;
  1669. int dgx = dSizeA[doa].x;
  1670. int dgy = dSizeA[doa].y;
  1671. x += drawOff[doa].x;
  1672. y += drawOff[doa].y;
  1673. if (x + hi < dpx || y + br < dpy || x >= dgx || y >= dgy) return;
  1674. br = minInt(br, zImage.getHeight());
  1675. hi = minInt(hi, zImage.getWidth());
  1676. int xst = maxInt(dpx - x, 0);
  1677. int yst = maxInt(dpy - y, 0);
  1678. int xst2 = maxInt(x, dpx);
  1679. int yst2 = maxInt(y, dpy);
  1680. dgx = minInt(x + br, dgx);
  1681. dgy = minInt(y + hi, dgy);
  1682. int bb = zImage.getWidth();
  1683. int* ff = zImage.getBuffer();
  1684. int yy, xbb;
  1685. for (int xx = xst2; xx < dgx; ++xx)
  1686. {
  1687. xbb = (zImage.getHeight() - (xx - xst2 + xst + 1)) * bb;
  1688. for (yy = yst2; yy < dgy; ++yy)
  1689. fc[xx + yy * size.x] = ff[(yy - yst2 + yst) + xbb];
  1690. }
  1691. rend = 1;
  1692. }
  1693. void Image::alphaImage90(int x, int y, int br, int hi, const Image& zImage)
  1694. {
  1695. if (alpha[alphaCount] == 0xFF) return;
  1696. int dpx = dPosA[doa].x;
  1697. int dpy = dPosA[doa].y;
  1698. int dgx = dSizeA[doa].x;
  1699. int dgy = dSizeA[doa].y;
  1700. x += drawOff[doa].x;
  1701. y += drawOff[doa].y;
  1702. if (x + hi < dpx || y + br < dpy || x >= dgx || y >= dgy) return;
  1703. br = minInt(br, zImage.getHeight());
  1704. hi = minInt(hi, zImage.getWidth());
  1705. int xst = maxInt(dpx - x, 0);
  1706. int yst = maxInt(dpy - y, 0);
  1707. int xst2 = maxInt(x, dpx);
  1708. int yst2 = maxInt(y, dpy);
  1709. dgx = minInt(x + br, dgx);
  1710. dgy = minInt(y + hi, dgy);
  1711. int bb = zImage.getWidth();
  1712. int* ff = zImage.getBuffer();
  1713. if (!alpha[alphaCount])
  1714. {
  1715. int yy, xbb;
  1716. if (alpha3D)
  1717. {
  1718. for (int xx = xst2; xx < dgx; ++xx)
  1719. {
  1720. xbb = (zImage.getHeight() - (xx - xst2 + xst + 1)) * bb;
  1721. for (yy = yst2; yy < dgy; ++yy)
  1722. alphaPixelP3D(xx, yy, ff[(yy - yst2 + yst) + xbb]);
  1723. }
  1724. }
  1725. else
  1726. {
  1727. for (int xx = xst2; xx < dgx; ++xx)
  1728. {
  1729. xbb = (zImage.getHeight() - (xx - xst2 + xst + 1)) * bb;
  1730. for (yy = yst2; yy < dgy; ++yy)
  1731. alphaPixelP(xx, yy, ff[(yy - yst2 + yst) + xbb]);
  1732. }
  1733. }
  1734. }
  1735. else
  1736. {
  1737. int yy, xbb;
  1738. if (alpha3D)
  1739. {
  1740. for (int xx = xst2; xx < dgx; ++xx)
  1741. {
  1742. xbb = (zImage.getHeight() - (xx - xst2 + xst + 1)) * bb;
  1743. for (yy = yst2; yy < dgy; ++yy)
  1744. {
  1745. int fc = ff[(yy - yst2 + yst) + xbb];
  1746. unsigned char* cf = (unsigned char*)&fc;
  1747. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  1748. * (cf[3] - alpha[alphaCount]));
  1749. alphaPixelP3D(xx, yy, fc);
  1750. }
  1751. }
  1752. }
  1753. else
  1754. {
  1755. for (int xx = xst2; xx < dgx; ++xx)
  1756. {
  1757. xbb = (zImage.getHeight() - (xx - xst2 + xst + 1)) * bb;
  1758. for (yy = yst2; yy < dgy; ++yy)
  1759. {
  1760. int fc = ff[(yy - yst2 + yst) + xbb];
  1761. unsigned char* cf = (unsigned char*)&fc;
  1762. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  1763. * (cf[3] - alpha[alphaCount]));
  1764. alphaPixelP(xx, yy, fc);
  1765. }
  1766. }
  1767. }
  1768. }
  1769. rend = 1;
  1770. }
  1771. void Image::drawImage180(int x,
  1772. int y,
  1773. int br,
  1774. int hi,
  1775. const Image& zImage) // Draws an image rotated 180 degrees to the right
  1776. {
  1777. if (alpha[alphaCount] == 0xFF) return;
  1778. if (alpha[alphaCount])
  1779. {
  1780. alphaImage180(x, y, br, hi, zImage);
  1781. return;
  1782. }
  1783. int dpx = dPosA[doa].x;
  1784. int dpy = dPosA[doa].y;
  1785. int dgx = dSizeA[doa].x;
  1786. int dgy = dSizeA[doa].y;
  1787. x += drawOff[doa].x;
  1788. y += drawOff[doa].y;
  1789. if (x + br < dpx || y + hi < dpy || x >= dgx || y >= dgy) return;
  1790. br = minInt(br, zImage.getWidth());
  1791. hi = minInt(hi, zImage.getHeight());
  1792. int xst = maxInt(dpx - x, 0);
  1793. int yst = maxInt(dpy - y, 0);
  1794. int xst2 = maxInt(x, dpx);
  1795. int yst2 = maxInt(y, dpy);
  1796. dgx = minInt(x + br, dgx);
  1797. dgy = minInt(y + hi, dgy);
  1798. int bb = zImage.getWidth();
  1799. int* ff = zImage.getBuffer();
  1800. int xx, ygr, ybb;
  1801. for (int yy = yst2; yy < dgy; ++yy)
  1802. {
  1803. ygr = yy * size.x;
  1804. ybb = (zImage.getHeight() - (yy - yst2 + yst + 1)) * bb;
  1805. for (xx = xst2; xx < dgx; ++xx)
  1806. fc[xx + ygr] = ff[(bb - (xx - xst2 + xst + 1)) + ybb];
  1807. }
  1808. rend = 1;
  1809. }
  1810. void Image::alphaImage180(int x, int y, int br, int hi, const Image& zImage)
  1811. {
  1812. if (alpha[alphaCount] == 0xFF) return;
  1813. int dpx = dPosA[doa].x;
  1814. int dpy = dPosA[doa].y;
  1815. int dgx = dSizeA[doa].x;
  1816. int dgy = dSizeA[doa].y;
  1817. x += drawOff[doa].x;
  1818. y += drawOff[doa].y;
  1819. if (x + br < dpx || y + hi < dpy || x >= dgx || y >= dgy) return;
  1820. br = minInt(br, zImage.getHeight());
  1821. hi = minInt(hi, zImage.getWidth());
  1822. int xst = maxInt(dpx - x, 0);
  1823. int yst = maxInt(dpy - y, 0);
  1824. int xst2 = maxInt(x, dpx);
  1825. int yst2 = maxInt(y, dpy);
  1826. dgx = minInt(x + br, dgx);
  1827. dgy = minInt(y + hi, dgy);
  1828. int bb = zImage.getWidth();
  1829. int* ff = zImage.getBuffer();
  1830. if (!alpha[alphaCount])
  1831. {
  1832. int xx, ygr, ybb;
  1833. if (alpha3D)
  1834. {
  1835. for (int yy = yst2; yy < dgy; ++yy)
  1836. {
  1837. ygr = yy * size.x;
  1838. ybb = (zImage.getHeight() - (yy - yst2 + yst + 1)) * bb;
  1839. for (xx = xst2; xx < dgx; ++xx)
  1840. alphaPixelP3D(
  1841. fc[xx + ygr], ff[(bb - (xx - xst2 + xst + 1)) + ybb]);
  1842. }
  1843. }
  1844. else
  1845. {
  1846. for (int yy = yst2; yy < dgy; ++yy)
  1847. {
  1848. ygr = yy * size.x;
  1849. ybb = (zImage.getHeight() - (yy - yst2 + yst + 1)) * bb;
  1850. for (xx = xst2; xx < dgx; ++xx)
  1851. alphaPixelP(
  1852. fc[xx + ygr], ff[(bb - (xx - xst2 + xst + 1)) + ybb]);
  1853. }
  1854. }
  1855. }
  1856. else
  1857. {
  1858. int xx, ygr, ybb;
  1859. if (alpha3D)
  1860. {
  1861. for (int yy = yst2; yy < dgy; ++yy)
  1862. {
  1863. ygr = yy * size.x;
  1864. ybb = (zImage.getHeight() - (yy - yst2 + yst + 1)) * bb;
  1865. for (xx = xst2; xx < dgx; ++xx)
  1866. {
  1867. int fc = ff[(bb - (xx - xst2 + xst + 1)) + ybb];
  1868. unsigned char* cf = (unsigned char*)&fc;
  1869. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  1870. * (cf[3] - alpha[alphaCount]));
  1871. alphaPixelP3D(this->fc[xx + ygr], fc);
  1872. }
  1873. }
  1874. }
  1875. else
  1876. {
  1877. for (int yy = yst2; yy < dgy; ++yy)
  1878. {
  1879. ygr = yy * size.x;
  1880. ybb = (zImage.getHeight() - (yy - yst2 + yst + 1)) * bb;
  1881. for (xx = xst2; xx < dgx; ++xx)
  1882. {
  1883. int fc = ff[(bb - (xx - xst2 + xst + 1)) + ybb];
  1884. unsigned char* cf = (unsigned char*)&fc;
  1885. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  1886. * (cf[3] - alpha[alphaCount]));
  1887. alphaPixelP(this->fc[xx + ygr], fc);
  1888. }
  1889. }
  1890. }
  1891. }
  1892. rend = 1;
  1893. }
  1894. void Image::drawImage270(int x,
  1895. int y,
  1896. int br,
  1897. int hi,
  1898. const Image& zImage) // Draws an image rotated 270 degrees to the right
  1899. {
  1900. if (alpha[alphaCount] == 0xFF) return;
  1901. if (alpha[alphaCount])
  1902. {
  1903. alphaImage270(x, y, br, hi, zImage);
  1904. return;
  1905. }
  1906. int dpx = dPosA[doa].x;
  1907. int dpy = dPosA[doa].y;
  1908. int dgx = dSizeA[doa].x;
  1909. int dgy = dSizeA[doa].y;
  1910. x += drawOff[doa].x;
  1911. y += drawOff[doa].y;
  1912. if (x + hi < dpx || y + br < dpy || x >= dgx || y >= dgy) return;
  1913. br = minInt(br, zImage.getHeight());
  1914. hi = minInt(hi, zImage.getWidth());
  1915. int xst = maxInt(dpx - x, 0);
  1916. int yst = maxInt(dpy - y, 0);
  1917. int xst2 = maxInt(x, dpx);
  1918. int yst2 = maxInt(y, dpy);
  1919. dgx = minInt(x + br, dgx);
  1920. dgy = minInt(y + hi, dgy);
  1921. int bb = zImage.getWidth();
  1922. int* ff = zImage.getBuffer();
  1923. int yy, xbb;
  1924. for (int xx = xst2; xx < dgx; ++xx)
  1925. {
  1926. xbb = (xx - xst2 + xst) * bb;
  1927. for (yy = yst2; yy < dgy; ++yy)
  1928. fc[xx + yy * size.x] = ff[(bb - (yy - yst2 + yst + 1)) + xbb];
  1929. }
  1930. rend = 1;
  1931. }
  1932. void Image::alphaImage270(int x, int y, int br, int hi, const Image& zImage)
  1933. {
  1934. if (alpha[alphaCount] == 0xFF) return;
  1935. int dpx = dPosA[doa].x;
  1936. int dpy = dPosA[doa].y;
  1937. int dgx = dSizeA[doa].x;
  1938. int dgy = dSizeA[doa].y;
  1939. x += drawOff[doa].x;
  1940. y += drawOff[doa].y;
  1941. if (x + hi < dpx || y + br < dpy || x >= dgx || y >= dgy) return;
  1942. br = minInt(br, zImage.getHeight());
  1943. hi = minInt(hi, zImage.getWidth());
  1944. int xst = maxInt(dpx - x, 0);
  1945. int yst = maxInt(dpy - y, 0);
  1946. int xst2 = maxInt(x, dpx);
  1947. int yst2 = maxInt(y, dpy);
  1948. dgx = minInt(x + br, dgx);
  1949. dgy = minInt(y + hi, dgy);
  1950. int bb = zImage.getWidth();
  1951. int* ff = zImage.getBuffer();
  1952. if (!alpha[alphaCount])
  1953. {
  1954. int yy, xbb;
  1955. if (alpha3D)
  1956. {
  1957. for (int xx = xst2; xx < dgx; ++xx)
  1958. {
  1959. xbb = (xx - xst2 + xst) * bb;
  1960. for (yy = yst2; yy < dgy; ++yy)
  1961. alphaPixelP3D(
  1962. xx, yy, ff[(bb - (yy - yst2 + yst + 1)) + xbb]);
  1963. }
  1964. }
  1965. else
  1966. {
  1967. for (int xx = xst2; xx < dgx; ++xx)
  1968. {
  1969. xbb = (xx - xst2 + xst) * bb;
  1970. for (yy = yst2; yy < dgy; ++yy)
  1971. alphaPixelP(xx, yy, ff[(bb - (yy - yst2 + yst + 1)) + xbb]);
  1972. }
  1973. }
  1974. }
  1975. else
  1976. {
  1977. int yy, xbb;
  1978. if (alpha3D)
  1979. {
  1980. for (int xx = xst2; xx < dgx; ++xx)
  1981. {
  1982. xbb = (xx - xst2 + xst) * bb;
  1983. for (yy = yst2; yy < dgy; ++yy)
  1984. {
  1985. int fc = ff[(bb - (yy - yst2 + yst + 1)) + xbb];
  1986. unsigned char* cf = (unsigned char*)&fc;
  1987. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  1988. * (cf[3] - alpha[alphaCount]));
  1989. alphaPixelP3D(xx, yy, fc);
  1990. }
  1991. }
  1992. }
  1993. else
  1994. {
  1995. for (int xx = xst2; xx < dgx; ++xx)
  1996. {
  1997. xbb = (xx - xst2 + xst) * bb;
  1998. for (yy = yst2; yy < dgy; ++yy)
  1999. {
  2000. int fc = ff[(bb - (yy - yst2 + yst + 1)) + xbb];
  2001. unsigned char* cf = (unsigned char*)&fc;
  2002. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  2003. * (cf[3] - alpha[alphaCount]));
  2004. alphaPixelP(xx, yy, fc);
  2005. }
  2006. }
  2007. }
  2008. }
  2009. rend = 1;
  2010. }
  2011. void Image::drawImageScaled(
  2012. int x, int y, int br, int hi, const Image& zImage) // draws zImage scaled
  2013. {
  2014. if (alpha[alphaCount] == 0xFF) return;
  2015. if (alpha[alphaCount])
  2016. {
  2017. alphaImageScaled(x, y, br, hi, zImage);
  2018. return;
  2019. }
  2020. int dpx = dPosA[doa].x;
  2021. int dpy = dPosA[doa].y;
  2022. int dgx = dSizeA[doa].x;
  2023. int dgy = dSizeA[doa].y;
  2024. x += drawOff[doa].x;
  2025. y += drawOff[doa].y;
  2026. if (x + br < dpx || y + hi < dpy || x >= dgx || y >= dgy) return;
  2027. double xo = zImage.getWidth() / (double)br;
  2028. double yo = zImage.getHeight() / (double)hi;
  2029. int xst = maxInt(dpx - x, 0);
  2030. int yst = maxInt(dpy - y, 0);
  2031. int xst2 = maxInt(x, dpx);
  2032. int yst2 = maxInt(y, dpy);
  2033. dgx = minInt(x + br, dgx);
  2034. dgy = minInt(y + hi, dgy);
  2035. int bb = zImage.getWidth();
  2036. int* ff = zImage.getBuffer();
  2037. int xx, ygr, ygr2;
  2038. double xb = 0, yb = yst * yo;
  2039. for (int yy = yst2; yy < dgy; ++yy, yb += yo)
  2040. {
  2041. ygr = yy * size.x;
  2042. ygr2 = (int)((yy - yst2 + yst) * yo) * bb;
  2043. for (xx = xst2, xb = xst * xo; xx < dgx; ++xx, xb += xo)
  2044. fc[xx + ygr] = ff[(int)xb + ygr2];
  2045. }
  2046. rend = 1;
  2047. }
  2048. void Image::alphaImageScaled(int x, int y, int br, int hi, const Image& zImage)
  2049. {
  2050. if (alpha[alphaCount] == 0xFF) return;
  2051. int dpx = dPosA[doa].x;
  2052. int dpy = dPosA[doa].y;
  2053. int dgx = dSizeA[doa].x;
  2054. int dgy = dSizeA[doa].y;
  2055. x += drawOff[doa].x;
  2056. y += drawOff[doa].y;
  2057. if (x + br < dpx || y + hi < dpy || x >= dgx || y >= dgy) return;
  2058. double xo = zImage.getWidth() / (double)br;
  2059. double yo = zImage.getHeight() / (double)hi;
  2060. int xst = maxInt(dpx - x, 0);
  2061. int yst = maxInt(dpy - y, 0);
  2062. int xst2 = maxInt(x, dpx);
  2063. int yst2 = maxInt(y, dpy);
  2064. dgx = minInt(x + br, dgx);
  2065. dgy = minInt(y + hi, dgy);
  2066. int bb = zImage.getWidth();
  2067. int* ff = zImage.getBuffer();
  2068. int xx, ygr, ygr2;
  2069. double xb = 0;
  2070. if (alpha3D)
  2071. {
  2072. for (int yy = yst2; yy < dgy; ++yy)
  2073. {
  2074. ygr = yy * size.x;
  2075. ygr2 = (int)((yy - yst2 + yst) * yo) * bb;
  2076. for (xx = xst2, xb = xst * xo; xx < dgx; ++xx, xb += xo)
  2077. {
  2078. int f = ff[(int)xb + ygr2];
  2079. unsigned char* cf = (unsigned char*)&f;
  2080. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  2081. * (cf[3] - alpha[alphaCount]));
  2082. alphaPixelP3D(fc[xx + ygr], f);
  2083. }
  2084. }
  2085. }
  2086. else
  2087. {
  2088. for (int yy = yst2; yy < dgy; ++yy)
  2089. {
  2090. ygr = yy * size.x;
  2091. ygr2 = (int)((yy - yst2 + yst) * yo) * bb;
  2092. for (xx = xst2, xb = xst * xo; xx < dgx; ++xx, xb += xo)
  2093. {
  2094. int f = ff[(int)xb + ygr2];
  2095. unsigned char* cf = (unsigned char*)&f;
  2096. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  2097. * (cf[3] - alpha[alphaCount]));
  2098. alphaPixelP(fc[xx + ygr], f);
  2099. }
  2100. }
  2101. }
  2102. rend = 1;
  2103. }
  2104. void Image::drawTriangle(
  2105. Point a, Point b, Point c, int color) // fills a triangle
  2106. {
  2107. if (alpha[alphaCount] == 0xFF) return;
  2108. if (alpha[alphaCount])
  2109. {
  2110. drawTriangleAlpha(a, b, c, color);
  2111. return;
  2112. }
  2113. int dpx = dPosA[doa].x;
  2114. int dpy = dPosA[doa].y;
  2115. int dgx = dSizeA[doa].x;
  2116. int dgy = dSizeA[doa].y;
  2117. a += drawOff[doa];
  2118. b += drawOff[doa];
  2119. c += drawOff[doa];
  2120. if ((a.x < dpx && b.x < dpx && c.x < dpx)
  2121. || (a.y < dpy && b.y < dpy && c.y < dpy)
  2122. || (a.x >= dgx && b.x >= dgx && c.x >= dgx)
  2123. || (a.y >= dgy && b.y >= dgy && c.y >= dgy))
  2124. return;
  2125. if (b.y < a.y) a.Swap(b);
  2126. if (c.y < b.y) b.Swap(c);
  2127. if (b.y < a.y) a.Swap(b);
  2128. if (a.y == b.y)
  2129. {
  2130. if (b.x < a.x) a.Swap(b);
  2131. const float m2 = (float)(a.x - c.x) / (float)(a.y - c.y);
  2132. const float m3 = (float)(b.x - c.x) / (float)(b.y - c.y);
  2133. float b2 = (float)a.x - m2 * (float)a.y;
  2134. float b3 = (float)b.x - m3 * (float)b.y;
  2135. drawFlatTriangle(b.y, c.y, m2, b2, m3, b3, color);
  2136. }
  2137. else if (b.y == c.y)
  2138. {
  2139. if (c.x < b.x) b.Swap(c);
  2140. const float m1 = (float)(a.x - b.x) / (float)(a.y - b.y);
  2141. const float m2 = (float)(a.x - c.x) / (float)(a.y - c.y);
  2142. float b1 = (float)a.x - m1 * (float)a.y;
  2143. float b2 = (float)a.x - m2 * (float)a.y;
  2144. drawFlatTriangle(a.y, b.y, m1, b1, m2, b2, color);
  2145. }
  2146. else
  2147. {
  2148. const float m1 = (float)(a.x - b.x) / (float)(a.y - b.y);
  2149. const float m2 = (float)(a.x - c.x) / (float)(a.y - c.y);
  2150. const float m3 = (float)(b.x - c.x) / (float)(b.y - c.y);
  2151. float b1 = (float)a.x - m1 * (float)a.y;
  2152. float b2 = (float)a.x - m2 * (float)a.y;
  2153. float b3 = (float)b.x - m3 * (float)b.y;
  2154. const float qx = m2 * (float)b.y + b2;
  2155. if (qx < (float)b.x)
  2156. {
  2157. drawFlatTriangle(a.y, b.y, m2, b2, m1, b1, color);
  2158. drawFlatTriangle(b.y, c.y, m2, b2, m3, b3, color);
  2159. }
  2160. else
  2161. {
  2162. drawFlatTriangle(a.y, b.y, m1, b1, m2, b2, color);
  2163. drawFlatTriangle(b.y, c.y, m3, b3, m2, b2, color);
  2164. }
  2165. }
  2166. rend = 1;
  2167. }
  2168. void Image::drawTriangleTexture(Point a,
  2169. Point b,
  2170. Point c,
  2171. Point ta,
  2172. Point tb,
  2173. Point tc,
  2174. const Image& textur) // fills a triangle
  2175. {
  2176. if (alpha[alphaCount] == 0xFF) return;
  2177. if (alpha[alphaCount])
  2178. {
  2179. drawTriangleTextureAlpha(a, b, c, ta, tb, tc, textur);
  2180. return;
  2181. }
  2182. int dpx = dPosA[doa].x;
  2183. int dpy = dPosA[doa].y;
  2184. int dgx = dSizeA[doa].x;
  2185. int dgy = dSizeA[doa].y;
  2186. a += drawOff[doa];
  2187. b += drawOff[doa];
  2188. c += drawOff[doa];
  2189. if ((a.x < dpx && b.x < dpx && c.x < dpx)
  2190. || (a.y < dpy && b.y < dpy && c.y < dpy)
  2191. || (a.x >= dgx && b.x >= dgx && c.x >= dgx)
  2192. || (a.y >= dgy && b.y >= dgy && c.y >= dgy))
  2193. return;
  2194. if (b.y < a.y)
  2195. {
  2196. a.Swap(b);
  2197. ta.Swap(tb);
  2198. }
  2199. if (c.y < b.y)
  2200. {
  2201. b.Swap(c);
  2202. tb.Swap(tc);
  2203. }
  2204. if (b.y < a.y)
  2205. {
  2206. a.Swap(b);
  2207. ta.Swap(tb);
  2208. }
  2209. const double m1 = (double)(a.x - b.x) / (a.y - b.y);
  2210. const double m2 = (double)(a.x - c.x) / (a.y - c.y);
  2211. const double m3 = (double)(b.x - c.x) / (b.y - c.y);
  2212. double b1 = a.x - m1 * a.y;
  2213. double b2 = a.x - m2 * a.y;
  2214. double b3 = b.x - m3 * b.y;
  2215. const double qx = m2 * b.y + b2;
  2216. if (qx < b.x)
  2217. {
  2218. double tx1o, ty1o, tx2o, ty2o;
  2219. if (c.y - a.y)
  2220. {
  2221. tx1o = (double)(tc.x - ta.x) / (c.y - a.y);
  2222. ty1o = (double)(tc.y - ta.y) / (c.y - a.y);
  2223. }
  2224. else
  2225. {
  2226. tx1o = 0;
  2227. ty1o = 0;
  2228. }
  2229. if (b.y - a.y)
  2230. {
  2231. tx2o = (double)(tb.x - ta.x) / (b.y - a.y);
  2232. ty2o = (double)(tb.y - ta.y) / (b.y - a.y);
  2233. }
  2234. else
  2235. {
  2236. tx2o = 0;
  2237. ty2o = 0;
  2238. }
  2239. Vec2<double> q(ta.x + tx1o * (b.y - a.y), ta.y + ty1o * (b.y - a.y));
  2240. double txf, tyf;
  2241. if (b.x - qx)
  2242. {
  2243. txf = (tb.x - q.x) / (b.x - qx);
  2244. tyf = (tb.y - q.y) / (b.x - qx);
  2245. }
  2246. else
  2247. {
  2248. txf = 0;
  2249. tyf = 0;
  2250. }
  2251. drawFlatTriangleTexture(a.y,
  2252. b.y,
  2253. m2,
  2254. b2,
  2255. m1,
  2256. b1,
  2257. ta.x,
  2258. ta.y,
  2259. ta.x,
  2260. ta.y,
  2261. tx1o,
  2262. ty1o,
  2263. tx2o,
  2264. ty2o,
  2265. txf,
  2266. tyf,
  2267. textur);
  2268. if (c.y - b.y)
  2269. {
  2270. tx2o = (double)(tc.x - tb.x) / (c.y - b.y);
  2271. ty2o = (double)(tc.y - tb.y) / (c.y - b.y);
  2272. }
  2273. else
  2274. {
  2275. tx2o = 0;
  2276. ty2o = 0;
  2277. }
  2278. drawFlatTriangleTexture(b.y,
  2279. c.y,
  2280. m2,
  2281. b2,
  2282. m3,
  2283. b3,
  2284. q.x,
  2285. q.y,
  2286. tb.x,
  2287. tb.y,
  2288. tx1o,
  2289. ty1o,
  2290. tx2o,
  2291. ty2o,
  2292. txf,
  2293. tyf,
  2294. textur);
  2295. }
  2296. else
  2297. {
  2298. double tx1o, ty1o, tx2o, ty2o;
  2299. if (b.y - a.y)
  2300. {
  2301. tx1o = (double)(tb.x - ta.x) / (b.y - a.y);
  2302. ty1o = (double)(tb.y - ta.y) / (b.y - a.y);
  2303. }
  2304. else
  2305. {
  2306. tx1o = 0;
  2307. ty1o = 0;
  2308. }
  2309. if (c.y - a.y)
  2310. {
  2311. tx2o = (double)(tc.x - ta.x) / (c.y - a.y);
  2312. ty2o = (double)(tc.y - ta.y) / (c.y - a.y);
  2313. }
  2314. else
  2315. {
  2316. tx2o = 0;
  2317. ty2o = 0;
  2318. }
  2319. Vec2<double> q(ta.x + tx2o * (b.y - a.y), ta.y + ty2o * (b.y - a.y));
  2320. double txf, tyf;
  2321. if (qx - b.x)
  2322. {
  2323. txf = (q.x - tb.x) / (qx - b.x);
  2324. tyf = (q.y - tb.y) / (qx - b.x);
  2325. }
  2326. else
  2327. {
  2328. txf = 0;
  2329. tyf = 0;
  2330. }
  2331. drawFlatTriangleTexture(a.y,
  2332. b.y,
  2333. m1,
  2334. b1,
  2335. m2,
  2336. b2,
  2337. ta.x,
  2338. ta.y,
  2339. ta.x,
  2340. ta.y,
  2341. tx1o,
  2342. ty1o,
  2343. tx2o,
  2344. ty2o,
  2345. txf,
  2346. tyf,
  2347. textur);
  2348. if (c.y - b.y)
  2349. {
  2350. tx1o = (double)(tc.x - tb.x) / (c.y - b.y);
  2351. ty1o = (double)(tc.y - tb.y) / (c.y - b.y);
  2352. }
  2353. else
  2354. {
  2355. tx1o = 0;
  2356. ty1o = 0;
  2357. }
  2358. drawFlatTriangleTexture(b.y,
  2359. c.y,
  2360. m3,
  2361. b3,
  2362. m2,
  2363. b2,
  2364. tb.x,
  2365. tb.y,
  2366. q.x,
  2367. q.y,
  2368. tx1o,
  2369. ty1o,
  2370. tx2o,
  2371. ty2o,
  2372. txf,
  2373. tyf,
  2374. textur);
  2375. }
  2376. rend = 1;
  2377. }
  2378. void Image::drawTriangleAlpha(
  2379. Point a, Point b, Point c, int color) // fills a triangle
  2380. {
  2381. if (alpha[alphaCount] == 0xFF) return;
  2382. int dpx = dPosA[doa].x;
  2383. int dpy = dPosA[doa].y;
  2384. int dgx = dSizeA[doa].x;
  2385. int dgy = dSizeA[doa].y;
  2386. a += drawOff[doa];
  2387. b += drawOff[doa];
  2388. c += drawOff[doa];
  2389. if ((a.x < dpx && b.x < dpx && c.x < dpx)
  2390. || (a.y < dpy && b.y < dpy && c.y < dpy)
  2391. || (a.x >= dgx && b.x >= dgx && c.x >= dgx)
  2392. || (a.y >= dgy && b.y >= dgy && c.y >= dgy))
  2393. return;
  2394. if (alpha[alphaCount])
  2395. {
  2396. unsigned char* cf = (unsigned char*)&color;
  2397. cf[3] = (unsigned char)((cf[3] > alpha[alphaCount])
  2398. * (cf[3] - alpha[alphaCount]));
  2399. }
  2400. if (b.y < a.y) a.Swap(b);
  2401. if (c.y < b.y) b.Swap(c);
  2402. if (b.y < a.y) a.Swap(b);
  2403. if (a.y == b.y)
  2404. {
  2405. if (b.x < a.x) a.Swap(b);
  2406. const float m2 = (float)(a.x - c.x) / (float)(a.y - c.y);
  2407. const float m3 = (float)(b.x - c.x) / (float)(b.y - c.y);
  2408. float b2 = (float)a.x - m2 * (float)a.y;
  2409. float b3 = (float)b.x - m3 * (float)b.y;
  2410. drawFlatTriangleAlpha(b.y, c.y, m2, b2, m3, b3, color);
  2411. }
  2412. else if (b.y == c.y)
  2413. {
  2414. if (c.x < b.x) b.Swap(c);
  2415. const float m1 = (float)(a.x - b.x) / (float)(a.y - b.y);
  2416. const float m2 = (float)(a.x - c.x) / (float)(a.y - c.y);
  2417. float b1 = (float)a.x - m1 * (float)a.y;
  2418. float b2 = (float)a.x - m2 * (float)a.y;
  2419. drawFlatTriangleAlpha(a.y, b.y, m1, b1, m2, b2, color);
  2420. }
  2421. else
  2422. {
  2423. const float m1 = (float)(a.x - b.x) / (float)(a.y - b.y);
  2424. const float m2 = (float)(a.x - c.x) / (float)(a.y - c.y);
  2425. const float m3 = (float)(b.x - c.x) / (float)(b.y - c.y);
  2426. float b1 = (float)a.x - m1 * (float)a.y;
  2427. float b2 = (float)a.x - m2 * (float)a.y;
  2428. float b3 = (float)b.x - m3 * (float)b.y;
  2429. const float qx = m2 * (float)b.y + b2;
  2430. if (qx < (float)b.x)
  2431. {
  2432. drawFlatTriangleAlpha(a.y, b.y, m2, b2, m1, b1, color);
  2433. drawFlatTriangleAlpha(b.y, c.y, m2, b2, m3, b3, color);
  2434. }
  2435. else
  2436. {
  2437. drawFlatTriangleAlpha(a.y, b.y, m1, b1, m2, b2, color);
  2438. drawFlatTriangleAlpha(b.y, c.y, m3, b3, m2, b2, color);
  2439. }
  2440. }
  2441. rend = 1;
  2442. }
  2443. void Image::drawTriangleTextureAlpha(Point a,
  2444. Point b,
  2445. Point c,
  2446. Point ta,
  2447. Point tb,
  2448. Point tc,
  2449. const Image& textur) // fills a triangle
  2450. {
  2451. if (alpha[alphaCount] == 0xFF) return;
  2452. int dpx = dPosA[doa].x;
  2453. int dpy = dPosA[doa].y;
  2454. int dgx = dSizeA[doa].x;
  2455. int dgy = dSizeA[doa].y;
  2456. a += drawOff[doa];
  2457. b += drawOff[doa];
  2458. c += drawOff[doa];
  2459. if ((a.x < dpx && b.x < dpx && c.x < dpx)
  2460. || (a.y < dpy && b.y < dpy && c.y < dpy)
  2461. || (a.x >= dgx && b.x >= dgx && c.x >= dgx)
  2462. || (a.y >= dgy && b.y >= dgy && c.y >= dgy))
  2463. return;
  2464. if (b.y < a.y)
  2465. {
  2466. a.Swap(b);
  2467. ta.Swap(tb);
  2468. }
  2469. if (c.y < b.y)
  2470. {
  2471. b.Swap(c);
  2472. tb.Swap(tc);
  2473. }
  2474. if (b.y < a.y)
  2475. {
  2476. a.Swap(b);
  2477. ta.Swap(tb);
  2478. }
  2479. const double m1 = (double)(a.x - b.x) / (a.y - b.y);
  2480. const double m2 = (double)(a.x - c.x) / (a.y - c.y);
  2481. const double m3 = (double)(b.x - c.x) / (b.y - c.y);
  2482. double b1 = a.x - m1 * a.y;
  2483. double b2 = a.x - m2 * a.y;
  2484. double b3 = b.x - m3 * b.y;
  2485. const double qx = m2 * b.y + b2;
  2486. if (qx < b.x)
  2487. {
  2488. double tx1o, ty1o, tx2o, ty2o;
  2489. if (c.y - a.y)
  2490. {
  2491. tx1o = (double)(tc.x - ta.x) / (c.y - a.y);
  2492. ty1o = (double)(tc.y - ta.y) / (c.y - a.y);
  2493. }
  2494. else
  2495. {
  2496. tx1o = 0;
  2497. ty1o = 0;
  2498. }
  2499. if (b.y - a.y)
  2500. {
  2501. tx2o = (double)(tb.x - ta.x) / (b.y - a.y);
  2502. ty2o = (double)(tb.y - ta.y) / (b.y - a.y);
  2503. }
  2504. else
  2505. {
  2506. tx2o = 0;
  2507. ty2o = 0;
  2508. }
  2509. Vec2<double> q(ta.x + tx1o * (b.y - a.y), ta.y + ty1o * (b.y - a.y));
  2510. double txf, tyf;
  2511. if (b.x - qx)
  2512. {
  2513. txf = (tb.x - q.x) / (b.x - qx);
  2514. tyf = (tb.y - q.y) / (b.x - qx);
  2515. }
  2516. else
  2517. {
  2518. txf = 0;
  2519. tyf = 0;
  2520. }
  2521. drawFlatTriangleTextureAlpha(a.y,
  2522. b.y,
  2523. m2,
  2524. b2,
  2525. m1,
  2526. b1,
  2527. ta.x,
  2528. ta.y,
  2529. ta.x,
  2530. ta.y,
  2531. tx1o,
  2532. ty1o,
  2533. tx2o,
  2534. ty2o,
  2535. txf,
  2536. tyf,
  2537. textur);
  2538. if (c.y - b.y)
  2539. {
  2540. tx2o = (double)(tc.x - tb.x) / (c.y - b.y);
  2541. ty2o = (double)(tc.y - tb.y) / (c.y - b.y);
  2542. }
  2543. else
  2544. {
  2545. tx2o = 0;
  2546. ty2o = 0;
  2547. }
  2548. drawFlatTriangleTextureAlpha(b.y,
  2549. c.y,
  2550. m2,
  2551. b2,
  2552. m3,
  2553. b3,
  2554. q.x,
  2555. q.y,
  2556. tb.x,
  2557. tb.y,
  2558. tx1o,
  2559. ty1o,
  2560. tx2o,
  2561. ty2o,
  2562. txf,
  2563. tyf,
  2564. textur);
  2565. }
  2566. else
  2567. {
  2568. double tx1o, ty1o, tx2o, ty2o;
  2569. if (b.y - a.y)
  2570. {
  2571. tx1o = (double)(tb.x - ta.x) / (b.y - a.y);
  2572. ty1o = (double)(tb.y - ta.y) / (b.y - a.y);
  2573. }
  2574. else
  2575. {
  2576. tx1o = 0;
  2577. ty1o = 0;
  2578. }
  2579. if (c.y - a.y)
  2580. {
  2581. tx2o = (double)(tc.x - ta.x) / (c.y - a.y);
  2582. ty2o = (double)(tc.y - ta.y) / (c.y - a.y);
  2583. }
  2584. else
  2585. {
  2586. tx2o = 0;
  2587. ty2o = 0;
  2588. }
  2589. Vec2<double> q(ta.x + tx2o * (b.y - a.y), ta.y + ty2o * (b.y - a.y));
  2590. double txf, tyf;
  2591. if (qx - b.x)
  2592. {
  2593. txf = (q.x - tb.x) / (qx - b.x);
  2594. tyf = (q.y - tb.y) / (qx - b.x);
  2595. }
  2596. else
  2597. {
  2598. txf = 0;
  2599. tyf = 0;
  2600. }
  2601. drawFlatTriangleTextureAlpha(a.y,
  2602. b.y,
  2603. m1,
  2604. b1,
  2605. m2,
  2606. b2,
  2607. ta.x,
  2608. ta.y,
  2609. ta.x,
  2610. ta.y,
  2611. tx1o,
  2612. ty1o,
  2613. tx2o,
  2614. ty2o,
  2615. txf,
  2616. tyf,
  2617. textur);
  2618. if (c.y - b.y)
  2619. {
  2620. tx1o = (double)(tc.x - tb.x) / (c.y - b.y);
  2621. ty1o = (double)(tc.y - tb.y) / (c.y - b.y);
  2622. }
  2623. else
  2624. {
  2625. tx1o = 0;
  2626. ty1o = 0;
  2627. }
  2628. drawFlatTriangleTextureAlpha(b.y,
  2629. c.y,
  2630. m3,
  2631. b3,
  2632. m2,
  2633. b2,
  2634. tb.x,
  2635. tb.y,
  2636. q.x,
  2637. q.y,
  2638. tx1o,
  2639. ty1o,
  2640. tx2o,
  2641. ty2o,
  2642. txf,
  2643. tyf,
  2644. textur);
  2645. }
  2646. rend = 1;
  2647. }
  2648. void Image::replaceColorWithAlpha(int color)
  2649. {
  2650. int r = (color & 0xFF0000) >> 16;
  2651. int g = (color & 0xFF00) >> 8;
  2652. int b = color & 0xFF;
  2653. int dx = drawOff[doa].x, dy = drawOff[doa].y;
  2654. int xx = dPosA[doa].x, yy = dPosA[doa].y;
  2655. int bb = dSizeA[doa].x, hh = dSizeA[doa].y;
  2656. for (int y = dy + yy; y < hh; y++)
  2657. {
  2658. int ygr = y * size.x;
  2659. for (int x = dx + xx; x < bb; x++)
  2660. {
  2661. unsigned char* cf = (unsigned char*)&(fc[x + ygr]);
  2662. int distance = (int)sqrt(
  2663. (float)((r - cf[2]) * (r - cf[2]) + (g - cf[1]) * (g - cf[1])
  2664. + (b - cf[0]) * (b - cf[0])));
  2665. if (distance > 255) distance = 255;
  2666. cf[3] = (unsigned char)(distance);
  2667. }
  2668. }
  2669. }
  2670. bool Image::setDrawOptions(
  2671. const Point& pos, const Point& gr) // sets the draw options
  2672. {
  2673. int dx = drawOff[doa].x, dy = drawOff[doa].y;
  2674. int xx = dPosA[doa].x, yy = dPosA[doa].y;
  2675. int bb = dSizeA[doa].x, hh = dSizeA[doa].y;
  2676. if (dx + pos.x + gr.x < 0 || dy + pos.y + gr.y < 0 || dx + pos.x >= size.x
  2677. || dy + pos.y >= size.y)
  2678. return 0;
  2679. if (pos.x + gr.x + dx < xx || pos.y + gr.y + dy < yy || dx + pos.x >= bb
  2680. || dy + pos.y >= hh)
  2681. return 0;
  2682. ++doa;
  2683. assert(doa < 2000);
  2684. dPosA[doa].x = maxInt(pos.x + dx, xx);
  2685. dPosA[doa].y = maxInt(pos.y + dy, yy);
  2686. dSizeA[doa].x = minInt(pos.x + gr.x + dx, bb);
  2687. dSizeA[doa].y = minInt(pos.y + gr.y + dy, hh);
  2688. drawOff[doa].x = dx + pos.x;
  2689. drawOff[doa].y = dy + pos.y;
  2690. return 1;
  2691. }
  2692. bool Image::setDrawOptions(int x, int y, int br, int hi)
  2693. {
  2694. int dx = drawOff[doa].x, dy = drawOff[doa].y;
  2695. int xx = dPosA[doa].x, yy = dPosA[doa].y;
  2696. int bb = dSizeA[doa].x, hh = dSizeA[doa].y;
  2697. if (dx + x + br < 0 || dy + y + hi < 0 || dx + x >= size.x
  2698. || dy + y >= size.y)
  2699. return 0;
  2700. if (x + br + dx < xx || y + hi + dy < yy || dx + x >= bb || dy + y >= hh)
  2701. return 0;
  2702. ++doa;
  2703. assert(doa < 2000);
  2704. dPosA[doa].x = maxInt(x + dx, xx);
  2705. dPosA[doa].y = maxInt(y + dy, yy);
  2706. dSizeA[doa].x = minInt(x + br + dx, bb);
  2707. dSizeA[doa].y = minInt(y + hi + dy, hh);
  2708. drawOff[doa].x = dx + x;
  2709. drawOff[doa].y = dy + y;
  2710. return 1;
  2711. }
  2712. bool Image::setDrawOptionsErzwingen(
  2713. const Point& pos, const Point& gr) // sets the draw options
  2714. {
  2715. int dx = drawOff[doa].x, dy = drawOff[doa].y;
  2716. if (dx + pos.x + gr.x < 0 || dy + pos.y + gr.y < 0 || dx + pos.x >= size.x
  2717. || dy + pos.y >= size.y)
  2718. return 0;
  2719. ++doa;
  2720. assert(doa < 2000);
  2721. dPosA[doa].x = maxInt(pos.x + dx, 0);
  2722. dPosA[doa].y = maxInt(pos.y + dy, 0);
  2723. dSizeA[doa].x = minInt(pos.x + gr.x + dx, size.x);
  2724. dSizeA[doa].y = minInt(pos.y + gr.y + dy, size.y);
  2725. drawOff[doa].x = dx + pos.x;
  2726. drawOff[doa].y = dy + pos.y;
  2727. return 1;
  2728. }
  2729. bool Image::setDrawOptionsErzwingen(
  2730. int x, int y, int br, int hi) // sets the draw options
  2731. {
  2732. int dx = drawOff[doa].x, dy = drawOff[doa].y;
  2733. if (dx + x + br < 0 || dy + y + hi < 0 || dx + x >= size.x
  2734. || dy + y >= size.y)
  2735. return 0;
  2736. ++doa;
  2737. assert(doa < 2000);
  2738. dPosA[doa].x = maxInt(x + dx, 0);
  2739. dPosA[doa].y = maxInt(y + dy, 0);
  2740. dSizeA[doa].x = minInt(x + br + dx, size.x);
  2741. dSizeA[doa].y = minInt(y + hi + dy, size.y);
  2742. drawOff[doa].x = dx + x;
  2743. drawOff[doa].y = dy + y;
  2744. return 1;
  2745. }
  2746. void Image::setDrawOptionsReset()
  2747. {
  2748. ++doa;
  2749. dPosA[doa].x = 0;
  2750. dPosA[doa].y = 0;
  2751. dSizeA[doa].x = size.x;
  2752. dSizeA[doa].y = size.y;
  2753. drawOff[doa].x = 0;
  2754. drawOff[doa].y = 0;
  2755. }
  2756. void Image::addScrollOffset(int xOff, int yOff) // sets scroll offset
  2757. {
  2758. drawOff[doa].x -= xOff;
  2759. drawOff[doa].y -= yOff;
  2760. }
  2761. void Image::releaseDrawOptions() // resets the draw options
  2762. {
  2763. --doa;
  2764. }
  2765. bool Image::getNeedRender()
  2766. {
  2767. bool ret = rend;
  2768. rend = 0;
  2769. return ret;
  2770. }
  2771. // constant
  2772. int* Image::getBuffer() const // returns the buffer
  2773. {
  2774. return fc;
  2775. }
  2776. int Image::getPixel(int x, int y) const
  2777. {
  2778. if (x < 0 || y < 0 || x >= size.x || y >= size.y) return 0;
  2779. return fc[x + y * size.x];
  2780. }
  2781. const Point& Image::getSize() const // returns the size
  2782. {
  2783. return size;
  2784. }
  2785. int Image::getWidth() const // returns the width
  2786. {
  2787. return size.x;
  2788. }
  2789. int Image::getHeight() const // returns the height
  2790. {
  2791. return size.y;
  2792. }
  2793. unsigned char Image::getAlpha() const // returns the alpha value
  2794. {
  2795. return (unsigned char)(255 - alpha[alphaCount]);
  2796. }
  2797. const Point& Image::getDrawPos() const
  2798. {
  2799. return dPosA[doa];
  2800. }
  2801. const Point& Image::getDrawGr() const
  2802. {
  2803. return dSizeA[doa];
  2804. }
  2805. const Point& Image::getDrawOff() const
  2806. {
  2807. return drawOff[doa];
  2808. }
  2809. bool Image::hasAlpha3D() const
  2810. {
  2811. return alpha3D;
  2812. }
  2813. int Image::getAverageColor() const
  2814. {
  2815. double a = 0;
  2816. double r = 0;
  2817. double g = 0;
  2818. double b = 0;
  2819. for (int i = 0; i < size.x * size.y; i++)
  2820. {
  2821. float currentA = (float)(fc[i] >> 24) / 255.f;
  2822. a = a + currentA;
  2823. r = r + (double)((float)((fc[i] >> 16) & 0xFF) * currentA);
  2824. g = g + (double)((float)((fc[i] >> 8) & 0xFF) * currentA);
  2825. b = b + (double)((float)(fc[i] & 0xFF) * currentA);
  2826. }
  2827. a = a / (size.x * size.y);
  2828. r = (r / (size.x * size.y)) / a;
  2829. g = (g / (size.x * size.y)) / a;
  2830. b = (b / (size.x * size.y)) / a;
  2831. a = a * 255;
  2832. return ((((int)a) & 0xFF) << 24) | ((((int)r) & 0xFF) << 16)
  2833. | ((((int)g) & 0xFF) << 8) | (((int)b) & 0xFF);
  2834. }
  2835. // Contents of the ImageView class from Image.h
  2836. // Constructor
  2837. ImageView::ImageView()
  2838. : DrawableBackground(),
  2839. bild(0)
  2840. {
  2841. style = 0;
  2842. mak = _ret1ME;
  2843. }
  2844. // Destructor
  2845. ImageView::~ImageView()
  2846. {
  2847. if (bild) bild->release();
  2848. }
  2849. void ImageView::doMouseEvent(MouseEvent& me, bool userRet) // calls Mak
  2850. {
  2851. if (userRet)
  2852. {
  2853. int rbr = 0;
  2854. if (hasStyle(Style::Border) && border) rbr = border->getRWidth();
  2855. bool vs = hasStyle(Style::VScroll) && vertikalScrollBar;
  2856. bool hs = hasStyle(Style::HScroll) && horizontalScrollBar;
  2857. if (vs)
  2858. {
  2859. if (hs)
  2860. horizontalScrollBar->doMouseMessage(
  2861. rbr, gr.y - rbr - 15, gr.x - rbr * 2 - 15, 15, me);
  2862. vertikalScrollBar->doMouseMessage(
  2863. gr.x - rbr - 15, rbr, 15, gr.y - rbr * 2, me);
  2864. }
  2865. else if (hs)
  2866. horizontalScrollBar->doMouseMessage(
  2867. rbr, gr.y - rbr - 15, gr.x - rbr * 2, 15, me);
  2868. }
  2869. me.processed = userRet;
  2870. }
  2871. // non-constant
  2872. void ImageView::setImageZ(Image* b) // sets the image
  2873. {
  2874. if (bild) bild->release();
  2875. bild = b;
  2876. if (!vertikalScrollBar) vertikalScrollBar = new VScrollBar();
  2877. if (!horizontalScrollBar) horizontalScrollBar = new HScrollBar();
  2878. if (b)
  2879. {
  2880. horizontalScrollBar->getScrollData()->max = b->getWidth();
  2881. vertikalScrollBar->getScrollData()->max = b->getHeight();
  2882. }
  2883. rend = 1;
  2884. }
  2885. void ImageView::setImage(Image* b)
  2886. {
  2887. if (!bild) bild = new Image();
  2888. bild->newImage(b->getWidth(), b->getHeight(), 0);
  2889. bild->drawImage(0, 0, b->getWidth(), b->getHeight(), *b);
  2890. if (!vertikalScrollBar) vertikalScrollBar = new VScrollBar();
  2891. if (!horizontalScrollBar) horizontalScrollBar = new HScrollBar();
  2892. horizontalScrollBar->getScrollData()->max = b->getWidth();
  2893. vertikalScrollBar->getScrollData()->max = b->getHeight();
  2894. b->release();
  2895. rend = 1;
  2896. }
  2897. bool ImageView::tick(double tickVal) // tick
  2898. {
  2899. return DrawableBackground::tick(tickVal);
  2900. }
  2901. void ImageView::render(Image& zRObj) // draws to zRObj
  2902. {
  2903. if (hasStyle(Style::Visible))
  2904. {
  2905. DrawableBackground::render(zRObj);
  2906. rwLock.lockRead();
  2907. if (!zRObj.setDrawOptions(innenPosition, innenSize))
  2908. {
  2909. rwLock.unlockRead();
  2910. return;
  2911. }
  2912. if (bild)
  2913. {
  2914. int x = 0;
  2915. int y = 0;
  2916. int br = innenSize.x;
  2917. int hi = innenSize.y;
  2918. if (!(vertikalScrollBar && hasStyle(Style::VScroll))
  2919. && !(horizontalScrollBar && hasStyle(Style::HScroll)))
  2920. {
  2921. if (hasStyle(Style::Alpha))
  2922. {
  2923. if (hasStyle(Style::Scaled))
  2924. zRObj.alphaImageScaled(x, y, br, hi, *bild);
  2925. else
  2926. zRObj.alphaImage(x, y, br, hi, *bild);
  2927. }
  2928. else
  2929. {
  2930. if (hasStyle(Style::Scaled))
  2931. zRObj.drawImageScaled(x, y, br, hi, *bild);
  2932. else
  2933. zRObj.drawImage(x, y, br, hi, *bild);
  2934. }
  2935. }
  2936. else
  2937. {
  2938. if (!zRObj.setDrawOptions(x, y, br, hi))
  2939. {
  2940. zRObj.releaseDrawOptions();
  2941. rwLock.unlockRead();
  2942. return;
  2943. }
  2944. if (hasStyle(Style::Alpha))
  2945. zRObj.alphaImage(-horizontalScrollBar->getScroll(),
  2946. -vertikalScrollBar->getScroll(),
  2947. bild->getWidth(),
  2948. bild->getHeight(),
  2949. *bild);
  2950. else
  2951. zRObj.drawImage(-horizontalScrollBar->getScroll(),
  2952. -vertikalScrollBar->getScroll(),
  2953. bild->getWidth(),
  2954. bild->getHeight(),
  2955. *bild);
  2956. zRObj.releaseDrawOptions();
  2957. }
  2958. }
  2959. zRObj.releaseDrawOptions();
  2960. rwLock.unlockRead();
  2961. }
  2962. }
  2963. // constant
  2964. Image* ImageView::getImage() const // returns the image
  2965. {
  2966. if (bild) return dynamic_cast<Image*>(bild->getThis());
  2967. return 0;
  2968. }
  2969. Image* ImageView::zImage() const
  2970. {
  2971. return bild;
  2972. }
  2973. Drawable* ImageView::duplicate() const // creates a copy of the drawing
  2974. {
  2975. ImageView* obj = new ImageView();
  2976. obj->setPosition(pos);
  2977. obj->setSize(gr);
  2978. obj->setMouseEventParameter(makParam);
  2979. obj->setKeyboardEventParameter(takParam);
  2980. obj->setMouseEvent(mak);
  2981. obj->setKeyboardEvent(tak);
  2982. if (toolTip) obj->setToolTipZ((ToolTip*)toolTip->duplicate());
  2983. obj->setStyle(style);
  2984. obj->setBackgroundColor(backgroundColor);
  2985. if (backgroundFeld)
  2986. obj->setAlphaFieldZ((AlphaField*)backgroundFeld->duplicate());
  2987. if (border) obj->setBorderZ((Border*)border->duplicate());
  2988. if (backgroundImage)
  2989. obj->setBackgroundImage(
  2990. dynamic_cast<Image*>(backgroundImage->getThis()));
  2991. if (bild) obj->setImage(dynamic_cast<Image*>(bild->getThis()));
  2992. obj->setStyle(style);
  2993. return obj;
  2994. }
  2995. #ifdef WIN32
  2996. Image* Framework::loadImage(const char* pfad, Text* zError)
  2997. {
  2998. Text p = pfad;
  2999. Text* txt = p.getTeilText(p.positionOf('.', p.countOf('.') - 1));
  3000. if (!(txt->isEqual(".bmp") || txt->isEqual(".jpg") || txt->isEqual(".gif")
  3001. || txt->isEqual(".png")))
  3002. {
  3003. zError->setText("Die Angegebene File ist keine gueltige ImageFile!");
  3004. txt->release();
  3005. return 0;
  3006. }
  3007. txt->release();
  3008. wchar_t* name = new wchar_t[p.getLength() + 1];
  3009. for (int i = 0; i < p.getLength(); i++)
  3010. name[i] = (wchar_t)p.getText()[i];
  3011. name[p.getLength()] = '\0';
  3012. Gdiplus::Bitmap bitmap(name);
  3013. Gdiplus::Color pix;
  3014. delete[] name;
  3015. Image* ret = new Image();
  3016. ret->newImage(bitmap.GetWidth(), bitmap.GetHeight(), 0);
  3017. int* buff = ret->getBuffer();
  3018. for (unsigned int i = 0; i < bitmap.GetWidth() * bitmap.GetHeight(); i++)
  3019. {
  3020. bitmap.GetPixel(i % bitmap.GetWidth(), i / bitmap.GetWidth(), &pix);
  3021. buff[i] = pix.GetValue();
  3022. }
  3023. return ret;
  3024. }
  3025. #endif