1
0

win32_canvas.cpp 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489
  1. #ifndef _WIN32
  2. #error this file is for windows only. Don't include it in your project/makefile for other platforms
  3. #else
  4. #include <tataki/export.h>
  5. #include <tataki/api__tataki.h>
  6. #include <tataki/blending/blending.h>
  7. #include "canvas.h"
  8. #include <tataki/bitmap/bitmap.h>
  9. #include <tataki/region/region.h>
  10. #include <api/wnd/basewnd.h>
  11. #include <api/wnd/fontdef.h>
  12. #include <api/wnd/paintsets.h>
  13. #include <bfc/assert.h>
  14. #include "bltcanvas.h"
  15. #include <nsutil/alpha.h>
  16. #include <nsutil/image.h>
  17. #define CBCLASS Canvas
  18. START_DISPATCH;
  19. CB(GETHDC, getHDC);
  20. CB(GETROOTWND, getRootWnd);
  21. CB(GETBITS, getBits);
  22. VCB(GETOFFSETS, getOffsets);
  23. CB(ISFIXEDCOORDS, isFixedCoords);
  24. CB(GETDIM, getDim);
  25. CB(GETTEXTFONT, getTextFont);
  26. CB(GETTEXTSIZE, getTextSize);
  27. CB(GETTEXTBOLD, getTextBold);
  28. CB(GETTEXTOPAQUE, getTextOpaque);
  29. CB(GETTEXTUNDERLINE, getTextUnderline);
  30. CB(GETTEXTITALIC, getTextItalic);
  31. CB(GETTEXTALIGN, getTextAlign);
  32. CB(GETTEXTCOLOR, getTextColor);
  33. CB(GETTEXTBKCOLOR, getTextBkColor);
  34. CB(GETTEXTAA, getTextAntialias);
  35. CB(GETCLIPBOX, getClipBox);
  36. END_DISPATCH;
  37. #undef CBCLASS
  38. //NONPORTABLE
  39. extern const wchar_t wasabi_default_fontnameW[];
  40. Canvas::Canvas()
  41. : hdc(NULL),
  42. bits(NULL),
  43. srcwnd(NULL),
  44. fcoord(FALSE),
  45. xoffset(0), yoffset(0),
  46. width(0),
  47. height(0),
  48. pitch(0),
  49. defpen(NULL),
  50. curpen(NULL),
  51. userFontInfo(0)
  52. {
  53. //tfont = new String; // using dynamic tfont here coz we need to manage em with stack, so stacking fonts won't take sizeof(String) and their destruction will not fuxor everything
  54. //tfont->setValue(wasabi_default_fontname);
  55. }
  56. Canvas::~Canvas()
  57. {
  58. if (getHDC() && defpen != NULL)
  59. {
  60. SelectObject(getHDC(), defpen);
  61. DeleteObject(curpen);
  62. }
  63. if (!penstack.isempty())
  64. DebugStringW(L"Pen stack not empty in Canvas::~Canvas !");
  65. }
  66. void Canvas::setBaseWnd(BaseWnd *b)
  67. {
  68. srcwnd = b;
  69. }
  70. HDC Canvas::getHDC()
  71. {
  72. return hdc;
  73. }
  74. ifc_window *Canvas::getRootWnd()
  75. {
  76. return srcwnd;
  77. }
  78. void *Canvas::getBits()
  79. {
  80. return bits;
  81. }
  82. bool Canvas::getDim(int *w, int *h, int *p)
  83. {
  84. if (w) *w = width;
  85. if (h) *h = height;
  86. if (p) *p = pitch;
  87. return FALSE;
  88. }
  89. void Canvas::getOffsets(int *x, int *y)
  90. {
  91. if (x != NULL) *x = getXOffset();
  92. if (y != NULL) *y = getYOffset();
  93. }
  94. bool Canvas::isFixedCoords()
  95. {
  96. return fcoord;
  97. }
  98. BaseWnd *Canvas::getBaseWnd()
  99. {
  100. return srcwnd;
  101. }
  102. void Canvas::fillRgn(RegionI *r, COLORREF color)
  103. {
  104. ASSERT(r != NULL);
  105. HBRUSH brush = CreateSolidBrush(color);
  106. FillRgn(hdc, r->getOSHandle(), brush);
  107. DeleteObject(brush);
  108. }
  109. void Canvas::fillRect(const RECT *r, COLORREF color)
  110. {
  111. ASSERT(r != NULL);
  112. #if 0
  113. HBRUSH brush;
  114. if (color == RGB(0, 0, 0))
  115. {
  116. FillRect(hdc, r, (HBRUSH)GetStockObject(BLACK_BRUSH));
  117. return ;
  118. }
  119. RECT rr = *r;
  120. offsetRect(&rr);
  121. brush = CreateSolidBrush(color);
  122. FillRect(hdc, &rr, brush);
  123. DeleteObject(brush);
  124. #else
  125. // see: http://ooeygui.typepad.com/ooey_gui/2005/06/tip_fast_solid_.html
  126. COLORREF clrOld = SetBkColor(hdc, color);
  127. RECT rr = *r;
  128. offsetRect(&rr);
  129. ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &rr, NULL, 0, NULL);
  130. SetBkColor(hdc, clrOld);
  131. #endif
  132. }
  133. void Canvas::fillRectAlpha(const RECT *r, COLORREF color, int alpha)
  134. {
  135. RECT blitr;
  136. RECT clipr;
  137. getClipBox(&clipr);
  138. IntersectRect(&blitr, &clipr, r);
  139. uint8_t *bits8 = (uint8_t *)(bits) + blitr.left*4 + blitr.top * pitch;
  140. nsutil_image_FillRectAlpha_RGB32((RGB32 *)(bits8), pitch, blitr.right-blitr.left, blitr.bottom-blitr.top, color, alpha);
  141. }
  142. void Canvas::drawRect(const RECT *r, int solid, COLORREF color, int alpha)
  143. {
  144. #if 0
  145. unsigned int blah = (unsigned int)alpha;
  146. color = RGBTOBGR(color);
  147. color = (color & 0xFFFFFF) | (blah << 24);
  148. BltCanvas::premultiply(&color, 1);
  149. int ox, oy;
  150. getOffsets(&ox, &oy);
  151. int w, h, pitch;
  152. getDim(&w, &h, &pitch);
  153. RECT _r = *r;
  154. _r.right = MIN<int>(r->right, w);
  155. _r.bottom = MIN<int>(r->bottom, h);
  156. int _l = r->bottom - r->top;
  157. int m = _r.bottom - _r.top;
  158. int l = _l;
  159. pitch /= 4;
  160. int *p = (int *)bits + ox + r->left + (oy + r->top) * pitch;
  161. int n = r->right - r->left;
  162. int maxn = _r.right - _r.left;
  163. while (l-- && m--)
  164. {
  165. int _n = maxn;
  166. if (l == _l - 1 || !l)
  167. {
  168. if (solid)
  169. {
  170. while (_n--)
  171. {
  172. *p = Blenders::BLEND_ADJ2(*p, color);
  173. p++;
  174. }
  175. }
  176. else
  177. {
  178. while (_n--)
  179. {
  180. if (_n % 2) *p = Blenders::BLEND_ADJ2(*p, color);
  181. p++;
  182. }
  183. }
  184. p += n - maxn;
  185. }
  186. else
  187. {
  188. if (solid || l % 2)
  189. *p = Blenders::BLEND_ADJ2(*p, color);
  190. p += n - 1;
  191. if (n == maxn && (solid || l % 2))
  192. *p = Blenders::BLEND_ADJ2(*p, color);
  193. p++;
  194. }
  195. p += pitch - n;
  196. }
  197. #else
  198. HBRUSH oldbrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
  199. HPEN oldpen, pen;
  200. pen = CreatePen(solid ? PS_SOLID : PS_DOT, 0, color);
  201. oldpen = (HPEN)SelectObject(hdc, pen);
  202. ASSERT(r != NULL);
  203. RECT rr = *r;
  204. offsetRect(&rr);
  205. Rectangle(hdc, rr.left, rr.top, rr.right, rr.bottom);
  206. SelectObject(hdc, oldpen);
  207. SelectObject(hdc, oldbrush);
  208. DeleteObject(pen);
  209. #endif
  210. }
  211. int Canvas::getTextAlign()
  212. {
  213. return getFontInfo()->alignFlags;
  214. }
  215. int Canvas::getTextOpaque()
  216. {
  217. return getFontInfo()->opaque;
  218. }
  219. int Canvas::getTextUnderline()
  220. {
  221. return getFontInfo()->underline;
  222. }
  223. int Canvas::getTextItalic()
  224. {
  225. return getFontInfo()->italic;
  226. }
  227. int Canvas::getTextBold()
  228. {
  229. return getFontInfo()->bold;
  230. }
  231. int Canvas::getTextAntialias()
  232. {
  233. return getFontInfo()->antialias;
  234. }
  235. void Canvas::pushPen(COLORREF color)
  236. {
  237. pushPen(PENSTYLE_SOLID, 1, color);
  238. }
  239. void Canvas::pushPen(int style, int width, COLORREF color)
  240. {
  241. ASSERT(getHDC() != NULL);
  242. penstyle = style;
  243. penwidth = width;
  244. pencolor = color;
  245. penstruct s;
  246. curpen = CreatePen(style, width, color);
  247. HPEN oldpen = (HPEN)SelectObject(getHDC(), curpen);
  248. s.style = style;
  249. s.width = width;
  250. s.color = color;
  251. s.hpen = oldpen;
  252. penstack.push(s);
  253. }
  254. void Canvas::popPen()
  255. {
  256. ASSERT(getHDC() != NULL);
  257. if (penstack.isempty()) return ;
  258. penstruct s;
  259. penstack.pop(&s);
  260. SelectObject(getHDC(), s.hpen);
  261. DeleteObject(curpen);
  262. }
  263. int Canvas::getPenStyle()
  264. {
  265. return penstyle;
  266. }
  267. COLORREF Canvas::getPenColor()
  268. {
  269. return pencolor;
  270. }
  271. int Canvas::getPenWidth()
  272. {
  273. return penwidth;
  274. }
  275. COLORREF Canvas::getTextColor()
  276. {
  277. return getFontInfo()->color;
  278. }
  279. COLORREF Canvas::getTextBkColor()
  280. {
  281. return getFontInfo()->bgColor;
  282. }
  283. int Canvas::getTextSize()
  284. {
  285. return getFontInfo()->pointSize;
  286. }
  287. const wchar_t *Canvas::getTextFont()
  288. {
  289. return getFontInfo()->face;
  290. }
  291. void Canvas::moveTo(int x, int y)
  292. {
  293. MoveToEx(hdc, x, y, NULL);
  294. }
  295. void Canvas::lineTo(int x, int y)
  296. {
  297. LineTo(hdc, x, y);
  298. }
  299. void Canvas::lineDraw(int fromX, int fromY, int toX, int toY)
  300. {
  301. MoveToEx(hdc, fromX, fromY, NULL);
  302. LineTo(hdc, toX, toY);
  303. }
  304. void Canvas::drawSysObject(const RECT *r, int sysobj, int alpha)
  305. {
  306. #ifndef _NOSTUDIO
  307. RECT i_dont_trust_ms_with_my_rect = *r;
  308. switch (sysobj)
  309. {
  310. case DrawSysObj::BUTTON:
  311. WASABI_API_WND->paintset_render(Paintset::BUTTONUP, this, r, alpha);
  312. break;
  313. case DrawSysObj::BUTTON_PUSHED:
  314. WASABI_API_WND->paintset_render(Paintset::BUTTONDOWN, this, r, alpha);
  315. break;
  316. case DrawSysObj::BUTTON_DISABLED:
  317. WASABI_API_WND->paintset_render(Paintset::BUTTONDISABLED, this, r, alpha);
  318. break;
  319. #ifdef WIN32
  320. case DrawSysObj::OSBUTTON:
  321. {
  322. DrawFrameControl(getHDC(), &i_dont_trust_ms_with_my_rect, DFC_BUTTON, DFCS_BUTTONPUSH);
  323. }
  324. break;
  325. case DrawSysObj::OSBUTTON_PUSHED:
  326. {
  327. DrawFrameControl(getHDC(), &i_dont_trust_ms_with_my_rect, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_PUSHED);
  328. }
  329. break;
  330. case DrawSysObj::OSBUTTON_DISABLED:
  331. {
  332. DrawFrameControl(getHDC(), &i_dont_trust_ms_with_my_rect, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_INACTIVE);
  333. }
  334. break;
  335. case DrawSysObj::OSBUTTON_CLOSE:
  336. {
  337. DrawFrameControl(getHDC(), &i_dont_trust_ms_with_my_rect, DFC_CAPTION, DFCS_CAPTIONCLOSE);
  338. }
  339. break;
  340. case DrawSysObj::OSBUTTON_CLOSE_PUSHED:
  341. {
  342. DrawFrameControl(getHDC(), &i_dont_trust_ms_with_my_rect, DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_PUSHED);
  343. }
  344. break;
  345. case DrawSysObj::OSBUTTON_CLOSE_DISABLED:
  346. {
  347. DrawFrameControl(getHDC(), &i_dont_trust_ms_with_my_rect, DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_INACTIVE);
  348. }
  349. break;
  350. case DrawSysObj::OSBUTTON_MINIMIZE:
  351. {
  352. DrawFrameControl(getHDC(), &i_dont_trust_ms_with_my_rect, DFC_CAPTION, DFCS_CAPTIONMIN);
  353. }
  354. break;
  355. case DrawSysObj::OSBUTTON_MINIMIZE_PUSHED:
  356. {
  357. DrawFrameControl(getHDC(), &i_dont_trust_ms_with_my_rect, DFC_CAPTION, DFCS_CAPTIONMIN | DFCS_PUSHED);
  358. }
  359. break;
  360. case DrawSysObj::OSBUTTON_MINIMIZE_DISABLED:
  361. {
  362. DrawFrameControl(getHDC(), &i_dont_trust_ms_with_my_rect, DFC_CAPTION, DFCS_CAPTIONMIN | DFCS_INACTIVE);
  363. }
  364. break;
  365. case DrawSysObj::OSBUTTON_MAXIMIZE:
  366. {
  367. DrawFrameControl(getHDC(), &i_dont_trust_ms_with_my_rect, DFC_CAPTION, DFCS_CAPTIONMAX);
  368. }
  369. break;
  370. case DrawSysObj::OSBUTTON_MAXIMIZE_PUSHED:
  371. {
  372. DrawFrameControl(getHDC(), &i_dont_trust_ms_with_my_rect, DFC_CAPTION, DFCS_CAPTIONMAX | DFCS_PUSHED);
  373. }
  374. break;
  375. case DrawSysObj::OSBUTTON_MAXIMIZE_DISABLED:
  376. {
  377. DrawFrameControl(getHDC(), &i_dont_trust_ms_with_my_rect, DFC_CAPTION, DFCS_CAPTIONMAX | DFCS_INACTIVE);
  378. }
  379. break;
  380. #else
  381. #error port me!
  382. #endif
  383. break;
  384. }
  385. #endif
  386. }
  387. void Canvas::textOut(int x, int y, const wchar_t *txt, const Wasabi::FontInfo *fontInfo)
  388. {
  389. userFontInfo = fontInfo;
  390. WASABI_API_FONT->font_textOut(this, WA_FONT_TEXTOUT_NORMAL, x, y, 0, 0, txt);
  391. userFontInfo = 0;
  392. }
  393. void Canvas::textOut(int x, int y, int w, int h, const wchar_t *txt, const Wasabi::FontInfo *fontInfo)
  394. {
  395. userFontInfo = fontInfo;
  396. WASABI_API_FONT->font_textOut(this, WA_FONT_TEXTOUT_RECT, x, y, w, h, txt);
  397. userFontInfo = 0;
  398. }
  399. void Canvas::textOutEllipsed(int x, int y, int w, int h, const wchar_t *txt, const Wasabi::FontInfo *fontInfo)
  400. {
  401. userFontInfo = fontInfo;
  402. WASABI_API_FONT->font_textOut(this, WA_FONT_TEXTOUT_ELLIPSED, x, y, w, h, txt);
  403. userFontInfo = 0;
  404. }
  405. void Canvas::textOutWrapped(int x, int y, int w, int h, const wchar_t *txt, const Wasabi::FontInfo *fontInfo)
  406. {
  407. userFontInfo = fontInfo;
  408. WASABI_API_FONT->font_textOut(this, WA_FONT_TEXTOUT_WRAPPED, x, y, w, h, (txt));
  409. userFontInfo = 0;
  410. }
  411. void Canvas::textOutWrappedPathed(int x, int y, int w, const wchar_t *txt, const Wasabi::FontInfo *fontInfo)
  412. {
  413. userFontInfo = fontInfo;
  414. WASABI_API_FONT->font_textOut(this, WA_FONT_TEXTOUT_WRAPPEDPATHED, x, y, w, 0, (txt));
  415. userFontInfo = 0;
  416. }
  417. void Canvas::textOutCentered(RECT *r, const wchar_t *txt, const Wasabi::FontInfo *fontInfo)
  418. {
  419. userFontInfo = fontInfo;
  420. WASABI_API_FONT->font_textOut(this, WA_FONT_TEXTOUT_CENTERED, r->left, r->top, r->right, r->bottom, (txt));
  421. userFontInfo = 0;
  422. }
  423. int Canvas::getTextWidth(const wchar_t *text, const Wasabi::FontInfo *fontInfo)
  424. {
  425. userFontInfo = fontInfo;
  426. int ret = WASABI_API_FONT->font_getInfo(this, fontInfo->face, WA_FONT_GETINFO_WIDTH, (text), NULL, NULL);
  427. userFontInfo = 0;
  428. return ret;
  429. }
  430. int Canvas::getTextHeight(const wchar_t *text, const Wasabi::FontInfo *fontInfo)
  431. {
  432. userFontInfo = fontInfo;
  433. int ret = WASABI_API_FONT->font_getInfo(this, fontInfo->face, WA_FONT_GETINFO_HEIGHT, (text), NULL, NULL);
  434. userFontInfo = 0;
  435. return ret;
  436. }
  437. void Canvas::getTextExtent(const wchar_t *txt, int *w, int *h, const Wasabi::FontInfo *fontInfo)
  438. {
  439. userFontInfo = fontInfo;
  440. WASABI_API_FONT->font_getInfo(this, fontInfo->face, WA_FONT_GETINFO_WIDTHHEIGHT, (txt), w, h);
  441. userFontInfo = 0;
  442. }
  443. void Canvas::offsetRect(RECT *r)
  444. {
  445. ASSERT(r != NULL);
  446. r->left += xoffset;
  447. r->right += xoffset;
  448. r->top += yoffset;
  449. r->bottom += yoffset;
  450. }
  451. void Canvas::selectClipRgn(api_region *r)
  452. {
  453. SelectClipRgn(hdc, r ? r->getOSHandle() : NULL);
  454. }
  455. int Canvas::getClipBox(RECT *r)
  456. {
  457. RECT dummy;
  458. if (!r) r = &dummy;
  459. return GetClipBox(hdc, r);
  460. }
  461. int Canvas::getClipRgn(api_region *r)
  462. {
  463. ASSERT(r != NULL);
  464. return GetClipRgn(hdc, r->getOSHandle());
  465. }
  466. //FG> added blit canvas to canvas
  467. void Canvas::blit(int srcx, int srcy, Canvas *dest, int dstx, int dsty, int dstw, int dsth)
  468. {
  469. char *srcbits = (char *)getBits();
  470. char *destbits = (char *)dest->getBits();
  471. RECT clipr;
  472. if (srcbits && destbits && GetClipBox(dest->getHDC(), &clipr) == SIMPLEREGION)
  473. {
  474. int srcimg_w, srcimg_h, srcimg_p;
  475. getDim(&srcimg_w, &srcimg_h, &srcimg_p);
  476. int dstimg_w, dstimg_h, dstimg_p;
  477. dest->getDim(&dstimg_w, &dstimg_h, &dstimg_p);
  478. if (srcx < 0)
  479. {
  480. dstx -= srcx; dstw += srcx; srcx = 0;
  481. }
  482. if (srcy < 0)
  483. {
  484. dsty -= srcy; dsth += srcy; srcy = 0;
  485. }
  486. if (srcx + dstw >= srcimg_w) dstw = srcimg_w - srcx;
  487. if (srcy + dsth >= srcimg_h) dsth = srcimg_h - srcy;
  488. if (dstx < clipr.left)
  489. {
  490. srcx += clipr.left - dstx; dstw -= clipr.left - dstx; dstx = clipr.left;
  491. }
  492. if (dsty < clipr.top)
  493. {
  494. srcy += clipr.top - dsty; dsth -= clipr.top - dsty; dsty = clipr.top;
  495. }
  496. if (dstx + dstw >= clipr.right) dstw = clipr.right - dstx;
  497. if (dsty + dsth >= clipr.bottom) dsth = clipr.bottom - dsty;
  498. if (!dstw || !dsth) return ;
  499. int y;
  500. int yl = dsty + dsth;
  501. for (y = dsty; y < yl; y++)
  502. {
  503. MEMCPY32(destbits + y*dstimg_p + dstx*4, srcbits + srcy*srcimg_p + srcx*4, dstw);
  504. srcy++;
  505. }
  506. }
  507. else
  508. {
  509. //GdiFlush();
  510. BitBlt(dest->getHDC(), dstx, dsty, dstw, dsth, getHDC(), srcx, srcy, SRCCOPY);
  511. }
  512. }
  513. #pragma comment(lib, "msimg32.lib")
  514. void Canvas::stretch(ifc_canvas *canvas, int x, int y, int w, int h)
  515. {
  516. if (bits)
  517. {
  518. SkinBitmap temp((ARGB32 *)bits, width, height);
  519. temp.stretch(canvas, x,y,w,h);
  520. }
  521. else
  522. {
  523. BLENDFUNCTION blendFn;
  524. blendFn.BlendOp = AC_SRC_OVER;
  525. blendFn.BlendFlags = 0;
  526. blendFn.SourceConstantAlpha = 255;
  527. blendFn.AlphaFormat = AC_SRC_ALPHA;
  528. AlphaBlend(canvas->getHDC(),
  529. x, y,
  530. w, h,
  531. getHDC(),
  532. 0, 0,
  533. width, height,
  534. blendFn);
  535. }
  536. }
  537. void Canvas::blitAlpha(ifc_canvas *canvas, int x, int y, int alpha)
  538. {
  539. if (bits)
  540. {
  541. SkinBitmap temp((ARGB32 *)bits, width, height);
  542. temp.blitAlpha(canvas, x,y,alpha);
  543. }
  544. else
  545. {
  546. BLENDFUNCTION blendFn;
  547. blendFn.BlendOp = AC_SRC_OVER;
  548. blendFn.BlendFlags = 0;
  549. blendFn.SourceConstantAlpha = alpha;
  550. blendFn.AlphaFormat = AC_SRC_ALPHA;
  551. AlphaBlend(canvas->getHDC(),
  552. x, y,
  553. width, height,
  554. getHDC(),
  555. 0, 0,
  556. width, height,
  557. blendFn);
  558. }
  559. }
  560. void Canvas::stretchToRectAlpha(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha)
  561. {
  562. if (bits)
  563. {
  564. SkinBitmap temp((ARGB32 *)bits, width, height);
  565. temp.stretchToRectAlpha(canvas, src, dst, alpha);
  566. }
  567. else
  568. {
  569. BLENDFUNCTION blendFn;
  570. blendFn.BlendOp = AC_SRC_OVER;
  571. blendFn.BlendFlags = 0;
  572. blendFn.SourceConstantAlpha = alpha;
  573. blendFn.AlphaFormat = AC_SRC_ALPHA;
  574. AlphaBlend(canvas->getHDC(),
  575. dst->left, dst->top,
  576. dst->right - dst->left, dst->bottom - dst->top,
  577. getHDC(),
  578. src->left, src->top,
  579. src->right - src->left, src->bottom - src->top,
  580. blendFn);
  581. }
  582. }
  583. void Canvas::blitToRect(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha)
  584. {
  585. if (bits)
  586. {
  587. SkinBitmap temp((ARGB32 *)bits, width, height);
  588. temp.blitToRect(canvas, src, dst, alpha);
  589. }
  590. else
  591. {
  592. BLENDFUNCTION blendFn;
  593. blendFn.BlendOp = AC_SRC_OVER;
  594. blendFn.BlendFlags = 0;
  595. blendFn.SourceConstantAlpha = alpha;
  596. blendFn.AlphaFormat = AC_SRC_ALPHA;
  597. AlphaBlend(canvas->getHDC(),
  598. dst->left, dst->top,
  599. dst->right - dst->left, dst->bottom - dst->top,
  600. getHDC(),
  601. src->left, src->top,
  602. src->right - src->left, src->bottom - src->top,
  603. blendFn);
  604. }
  605. }
  606. // src* are in fixed point
  607. static void scale_internal(int srcx, int srcy, int srcw, int srch, void *srcdib, int srcdib_w, int srcdib_h, int srcdib_p, int dstx, int dsty, int dstw, int dsth, void *dstdib, int nofilter)
  608. {
  609. // scaling up
  610. if ((dstw << 16) >= srcw && (dsth << 16) >= srch)
  611. {
  612. int y;
  613. int SY, dX, dY;
  614. int Xend = (srcdib_w - 2) << 16;
  615. SY = srcy;
  616. dX = srcw / dstw;
  617. dY = srch / dsth;
  618. int xstart = 0;
  619. int xp = srcx >> 16;
  620. if (xp < 0)
  621. {
  622. xstart = -xp;
  623. srcx += xstart * dX;
  624. }
  625. int xend = dstw;
  626. xp = (srcx + (dX * (xend - xstart))) >> 16;
  627. if (xp > srcdib_w)
  628. {
  629. xend = xstart + srcdib_w - (srcx >> 16);
  630. }
  631. for (y = 0; y < dsth; y ++)
  632. {
  633. int yp = (SY >> 16);
  634. if (yp >= 0)
  635. {
  636. int x;
  637. int SX = srcx;
  638. unsigned int *out = (unsigned int*)dstdib + xstart + y * dstw;
  639. int end = yp >= srcdib_h - 1;
  640. if (nofilter || end)
  641. {
  642. if (end) yp = srcdib_h - 1;
  643. unsigned int *in = (unsigned int*)((char *)srcdib + yp * srcdib_p);
  644. for (x = xstart; x < xend; x ++) // quick hack to draw last line
  645. {
  646. *out++ = in[SX >> 16];
  647. SX += dX;
  648. }
  649. if (end) break;
  650. }
  651. else
  652. {
  653. unsigned int *in = (unsigned int*)((char *)srcdib + yp * srcdib_p);
  654. #ifndef NO_MMX
  655. if (Blenders::MMX_AVAILABLE())
  656. {
  657. for (x = xstart; x < xend; x ++)
  658. {
  659. if (SX > Xend) *out++ = Blenders::BLEND4_MMX(in + (Xend >> 16), srcdib_w, 0xffff, SY);
  660. else *out++ = Blenders::BLEND4_MMX(in + (SX >> 16), srcdib_w, SX, SY);
  661. SX += dX;
  662. }
  663. }
  664. else
  665. #endif
  666. {
  667. for (x = xstart; x < xend; x ++)
  668. {
  669. if (SX > Xend) *out++ = Blenders::BLEND4(in + (Xend >> 16), srcdib_w, 0xffff, SY);
  670. else *out++ = Blenders::BLEND4(in + (SX >> 16), srcdib_w, SX, SY);
  671. SX += dX;
  672. }
  673. }
  674. }
  675. }
  676. SY += dY;
  677. }
  678. // end of scaling up
  679. }
  680. else // we are scaling down -- THIS IS SLOW AND MAY BREAK THINGS. :)
  681. {
  682. int y;
  683. int SY, dX, dY;
  684. SY = srcy;
  685. dX = srcw / dstw;
  686. dY = srch / dsth;
  687. int xstart = 0;
  688. int xp = srcx >> 16;
  689. if (xp < 0)
  690. {
  691. xstart = -xp;
  692. srcx += xstart * dX;
  693. }
  694. int xend = dstw;
  695. xp = (srcx + (dX * (xend - xstart))) >> 16;
  696. if (xp > srcdib_w)
  697. {
  698. xend = xstart + srcdib_w - (srcx >> 16);
  699. }
  700. for (y = 0; y < dsth; y ++)
  701. {
  702. // start and end of y source block
  703. int vStart = SY;
  704. int vEnd = SY + dY;
  705. int x;
  706. int SX = srcx;
  707. unsigned char *out = (unsigned char *)((unsigned int*)dstdib + xstart + y * dstw);
  708. for (x = xstart; x < xend; x ++)
  709. {
  710. if (((char *)out+4) >= ((char *)dstdib + 4*dstw*dsth))
  711. break;
  712. int uStart = SX;
  713. int uEnd = SX + dX;
  714. // calculate sum of rectangle.
  715. int cnt = 0;
  716. __int64 accum[4] = {0, };
  717. int v, u;
  718. for (v = vStart; v < vEnd; v += 65536)
  719. {
  720. unsigned int vscale = 65535;
  721. if (v == vStart)
  722. {
  723. vscale = 65535 - (v & 0xffff);
  724. }
  725. else if ((vEnd - v) < 65536)
  726. {
  727. vscale = (vEnd - v) & 0xffff;
  728. }
  729. int vp = v >> 16;
  730. unsigned char *in = (unsigned char*)((char *)srcdib + vp * srcdib_p + 4 * (uStart >> 16));
  731. for (u = uStart; u < uEnd; u += 65536)
  732. {
  733. if (((char *)in+4) >= ((char *)srcdib + srcdib_p*srcdib_h))
  734. break;
  735. unsigned int uscale = vscale;
  736. if (u == uStart)
  737. {
  738. uscale *= 65535 - (u & 0xffff);
  739. uscale >>= 16;
  740. }
  741. else if ((uEnd - u) < 65536)
  742. {
  743. uscale *= (uEnd - u) & 0xffff;
  744. uscale >>= 16;
  745. }
  746. cnt += uscale;
  747. if (uscale == 65535)
  748. {
  749. accum[0] += (in[0] << 16) - in[0];
  750. accum[1] += (in[1] << 16) - in[1];
  751. accum[2] += (in[2] << 16) - in[2];
  752. accum[3] += (in[3] << 16) - in[3];
  753. }
  754. else
  755. {
  756. accum[0] += in[0] * uscale;
  757. accum[1] += in[1] * uscale;
  758. accum[2] += in[2] * uscale;
  759. accum[3] += in[3] * uscale;
  760. }
  761. in += 4;
  762. }
  763. }
  764. if (!cnt) cnt++;
  765. out[0] = (uint8_t)(accum[0] / cnt);
  766. out[1] = (uint8_t)(accum[1] / cnt);
  767. out[2] = (uint8_t)(accum[2] / cnt);
  768. out[3] = (uint8_t)(accum[3] / cnt);
  769. out += 4;
  770. SX += dX;
  771. }
  772. SY += dY;
  773. }
  774. // end of scaling down
  775. }
  776. #ifndef NO_MMX
  777. Blenders::BLEND_MMX_END();
  778. #endif
  779. }
  780. // src* are in fixed point
  781. void Canvas::stretchblit(int srcx, int srcy, int srcw, int srch, Canvas *dest, int dstx, int dsty, int dstw, int dsth)
  782. {
  783. //GdiFlush();
  784. int done = 0;
  785. void *srcdib = getBits();
  786. if (!dstw || !dsth || !srcw || !srch) return ;
  787. if (srcdib)
  788. {
  789. int srcdib_w, srcdib_h, srcdib_p;
  790. getDim(&srcdib_w, &srcdib_h, &srcdib_p);
  791. void *dstdib;
  792. BITMAPINFO dstbmi = {0};
  793. HDC hMemDC;
  794. HBITMAP hsrcdib;
  795. dstbmi.bmiHeader.biSize = sizeof(dstbmi.bmiHeader);
  796. dstbmi.bmiHeader.biWidth = dstw;
  797. dstbmi.bmiHeader.biHeight = -ABS(dsth);
  798. dstbmi.bmiHeader.biPlanes = 1;
  799. dstbmi.bmiHeader.biBitCount = 32;
  800. dstbmi.bmiHeader.biCompression = BI_RGB;
  801. hMemDC = CreateCompatibleDC(NULL);
  802. hsrcdib = CreateDIBSection(hMemDC, &dstbmi, DIB_RGB_COLORS, &dstdib, NULL, 0);
  803. if (hsrcdib)
  804. {
  805. HBITMAP hprev = (HBITMAP)SelectObject(hMemDC, hsrcdib);
  806. scale_internal(srcx,srcy,srcw,srch,srcdib,srcdib_w,srcdib_h,srcdib_p,dstx,dsty,dstw,dsth,dstdib,0);
  807. BitBlt(dest->getHDC(), dstx, dsty, dstw, dsth, hMemDC, 0, 0, SRCCOPY);
  808. done++;
  809. SelectObject(hMemDC, hprev);
  810. DeleteObject(hsrcdib);
  811. }
  812. DeleteDC(hMemDC);
  813. }
  814. if (!done)
  815. {
  816. SetStretchBltMode(dest->getHDC(), COLORONCOLOR);
  817. StretchBlt(dest->getHDC(), dstx, dsty, dstw, dsth, getHDC(), srcx >> 16, srcy >> 16, srcw >> 16, srch >> 16, SRCCOPY);
  818. }
  819. }
  820. #define DEBUG_SCREEN_SHIFT 0
  821. void Canvas::debug()
  822. {
  823. SysCanvas c;
  824. int w, h;
  825. getDim(&w, &h, NULL);
  826. blit(0, 0, &c, DEBUG_SCREEN_SHIFT, 0, w, h);
  827. }
  828. #define BF2 (~((3<<24)|(3<<16)|(3<<8)|3))
  829. void Canvas::antiAliasTo(Canvas *dest, int w, int h, int aafactor)
  830. {
  831. ASSERT(aafactor != 0);
  832. if (aafactor == 1)
  833. {
  834. blit(0, 0, dest, 0, 0, w, h);
  835. return ;
  836. }
  837. ASSERT(getBits() != NULL);
  838. ASSERT(dest->getBits() != NULL);
  839. if (getBits() == NULL || dest->getBits() == NULL) return ;
  840. ASSERTPR(aafactor <= 2, "too lazy to generalize the code right now :)");
  841. //GdiFlush();
  842. // we should really store the bpp too
  843. int aaw = w * aafactor;
  844. unsigned long *s1 = (unsigned long *)getBits(), *s2 = s1 + 1;
  845. unsigned long *s3 = s1 + aaw, *s4 = s3 + 1;
  846. unsigned long *d = (unsigned long *)dest->getBits();
  847. #if 1
  848. for (int y = 0; y < h; y++)
  849. {
  850. for (int x = 0; x < w; x++)
  851. {
  852. unsigned long tmp = ((*s1 & BF2) >> 2) + ((*s2 & BF2) >> 2) + ((*s3 & BF2) >> 2) + ((*s4 & BF2) >> 2);
  853. *d++ = tmp;
  854. s1 += 2; s2 += 2;
  855. s3 += 2; s4 += 2;
  856. }
  857. s1 += aaw; s2 += aaw;
  858. s3 += aaw; s4 += aaw;
  859. }
  860. #else
  861. for (int x = 0; x < w * h; x++) d[x] = s1[x];
  862. #endif
  863. }
  864. void Canvas::colorToColor(COLORREF from, COLORREF to, RECT *r)
  865. {
  866. int w, h, ox, oy;
  867. // convert to bitmap order
  868. from = RGBTOBGR(from);
  869. to = RGBTOBGR(to);
  870. COLORREF *p;
  871. getDim(&w, &h, NULL);
  872. p = (COLORREF *)getBits();
  873. getOffsets(&ox, &oy);
  874. p += ox + r->left + (oy + r->top) * w;
  875. int rw = r->right - r->left;
  876. for (int j = r->top;j < r->bottom;j++)
  877. {
  878. for (int i = r->left;i < r->right;i++)
  879. {
  880. if (*p == from)
  881. *p = to;
  882. p++;
  883. }
  884. p += w - rw;
  885. }
  886. }
  887. double Canvas::getSystemFontScale()
  888. {
  889. if (WASABI_API_CONFIG)
  890. {
  891. int v = WASABI_API_CONFIG->getIntPublic(L"manualsysmetrics", -1);
  892. if (v != -1) return (v / 100.0f);
  893. }
  894. int nLogDPIX = GetDeviceCaps(getHDC(), LOGPIXELSX);
  895. return ((float)nLogDPIX / 96.0f);
  896. }
  897. void Canvas::premultiply(ARGB32 *m_pBits, int nwords, int newalpha)
  898. {
  899. if (newalpha == -1)
  900. {
  901. nsutil_alpha_Premultiply_RGB32(m_pBits, nwords, nwords, 1);
  902. /*
  903. for (; nwords > 0; nwords--, m_pBits++)
  904. {
  905. unsigned char *pixel = (unsigned char *)m_pBits;
  906. unsigned int alpha = pixel[3];
  907. if (alpha == 255) continue;
  908. pixel[0] = (pixel[0] * alpha) >> 8; // blue
  909. pixel[1] = (pixel[1] * alpha) >> 8; // green
  910. pixel[2] = (pixel[2] * alpha) >> 8; // red
  911. }
  912. */
  913. }
  914. else
  915. {
  916. nsutil_alpha_PremultiplyValue_RGB8(m_pBits, nwords, nwords, 1, newalpha);
  917. /*
  918. for (; nwords > 0; nwords--, m_pBits++)
  919. {
  920. unsigned char *pixel = (unsigned char *)m_pBits;
  921. pixel[0] = (pixel[0] * newalpha) >> 8; // blue
  922. pixel[1] = (pixel[1] * newalpha) >> 8; // green
  923. pixel[2] = (pixel[2] * newalpha) >> 8; // red
  924. pixel[3] = (pixel[3] * newalpha) >> 8; // alpha
  925. }
  926. */
  927. }
  928. }
  929. TextInfoCanvas::TextInfoCanvas(BaseWnd *basewnd)
  930. {
  931. ASSERT(basewnd != NULL);
  932. hWnd = basewnd->gethWnd();
  933. hdc = GetDC(hWnd);
  934. }
  935. TextInfoCanvas::~TextInfoCanvas()
  936. {
  937. if (hdc)
  938. ReleaseDC(hWnd, hdc);
  939. }
  940. WndCanvas::WndCanvas(BaseWnd *basewnd)
  941. {
  942. attachToClient(basewnd);
  943. }
  944. WndCanvas::WndCanvas()
  945. {
  946. hWnd = NULL;
  947. }
  948. WndCanvas::~WndCanvas()
  949. {
  950. if (hWnd != NULL && hdc != NULL) ReleaseDC(hWnd, hdc);
  951. hdc = NULL;
  952. }
  953. int WndCanvas::attachToClient(BaseWnd *basewnd)
  954. {
  955. if (basewnd == NULL)
  956. return 0;
  957. hWnd = basewnd->gethWnd();
  958. if (hWnd == NULL)
  959. return 0;
  960. hdc = GetDC(hWnd);
  961. if (hdc == NULL)
  962. return 0;
  963. srcwnd = basewnd;
  964. return 1;
  965. }
  966. #if 0//CUT
  967. int WndCanvas::attachToWnd(HWND _hWnd)
  968. {
  969. hWnd = _hWnd;
  970. ASSERT(hWnd != NULL);
  971. hdc = GetWindowDC(hWnd);
  972. ASSERT(hdc != NULL);
  973. return 1;
  974. }
  975. #endif
  976. PaintCanvas::PaintCanvas()
  977. {
  978. hWnd = NULL;
  979. }
  980. PaintCanvas::~PaintCanvas()
  981. {
  982. if (hdc != NULL) EndPaint(hWnd, &ps);
  983. hdc = NULL;
  984. }
  985. void PaintCanvas::getRcPaint(RECT *r)
  986. {
  987. *r = ps.rcPaint;
  988. }
  989. int PaintCanvas::beginPaint(BaseWnd *basewnd)
  990. {
  991. hWnd = basewnd->gethWnd(); // NONPORTABLE
  992. ASSERT(hWnd != NULL);
  993. hdc = BeginPaint(hWnd, &ps);
  994. ASSERT(hdc != NULL);
  995. srcwnd = basewnd;
  996. return 1;
  997. }
  998. int PaintCanvas::beginPaint(HWND wnd)
  999. {
  1000. hWnd = wnd; // NONPORTABLE
  1001. ASSERT(hWnd != NULL);
  1002. hdc = BeginPaint(hWnd, &ps);
  1003. ASSERT(hdc != NULL);
  1004. srcwnd = NULL;
  1005. return 1;
  1006. }
  1007. PaintBltCanvas::PaintBltCanvas()
  1008. {
  1009. hWnd = NULL;
  1010. wnddc = NULL;
  1011. hbmp = NULL;
  1012. prevbmp = NULL;
  1013. bits = NULL;
  1014. fcoord = TRUE;
  1015. nonclient = FALSE;
  1016. }
  1017. PaintBltCanvas::~PaintBltCanvas()
  1018. {
  1019. RECT r;
  1020. if (hdc == NULL) return ;
  1021. ASSERT(srcwnd != NULL);
  1022. if (nonclient) //FG> nonclient painting fix
  1023. srcwnd->getNonClientRect(&r);
  1024. else
  1025. srcwnd->getClientRect(&r);
  1026. // blt here
  1027. //GdiFlush();
  1028. BitBlt(wnddc, r.left, r.top, r.right - r.left, r.bottom - r.top, hdc, 0, 0, SRCCOPY);
  1029. //SelectClipRgn(hdc, NULL);
  1030. // kill the bitmap and its DC
  1031. SelectObject(hdc, prevbmp);
  1032. DeleteDC(hdc);
  1033. hdc = NULL;
  1034. DeleteObject(hbmp);
  1035. bits = NULL;
  1036. width = 0;
  1037. height = 0;
  1038. pitch = 0;
  1039. EndPaint(hWnd, &ps); // end of wnddc
  1040. wnddc = NULL;
  1041. }
  1042. //FG> nonclient painting fix
  1043. int PaintBltCanvas::beginPaintNC(BaseWnd *basewnd)
  1044. {
  1045. nonclient = TRUE;
  1046. return beginPaint(basewnd);
  1047. }
  1048. void PaintBltCanvas::getRcPaint(RECT *r)
  1049. {
  1050. *r = ps.rcPaint;
  1051. }
  1052. int PaintBltCanvas::beginPaint(BaseWnd *basewnd)
  1053. {
  1054. RECT r;
  1055. if (nonclient)
  1056. basewnd->getNonClientRect(&r); //FG> nonclient painting fix
  1057. else
  1058. basewnd->getClientRect(&r);
  1059. if (r.right - r.left <= 0 || r.bottom - r.top <= 0) return 0;
  1060. hWnd = basewnd->gethWnd(); // NONPORTABLE
  1061. ASSERT(hWnd != NULL);
  1062. BITMAPINFO bmi;
  1063. ZeroMemory(&bmi, sizeof bmi);
  1064. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  1065. bmi.bmiHeader.biWidth = r.right - r.left;
  1066. bmi.bmiHeader.biHeight = -(r.bottom - r.top);
  1067. bmi.bmiHeader.biPlanes = 1;
  1068. bmi.bmiHeader.biBitCount = 32;
  1069. bmi.bmiHeader.biCompression = BI_RGB;
  1070. bmi.bmiHeader.biSizeImage = 0;
  1071. bmi.bmiHeader.biXPelsPerMeter = 0;
  1072. bmi.bmiHeader.biYPelsPerMeter = 0;
  1073. bmi.bmiHeader.biClrUsed = 0;
  1074. bmi.bmiHeader.biClrImportant = 0;
  1075. wnddc = BeginPaint(hWnd, &ps);
  1076. ASSERT(wnddc != NULL);
  1077. //GdiFlush();
  1078. width = r.right - r.left;
  1079. height = -ABS(r.bottom - r.top);
  1080. pitch = width * 4;
  1081. hbmp = CreateDIBSection(wnddc, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
  1082. if (hbmp == NULL)
  1083. {
  1084. EndPaint(hWnd, &ps); // end of wnddc
  1085. wnddc = NULL;
  1086. return 0;
  1087. }
  1088. // create tha DC
  1089. hdc = CreateCompatibleDC(wnddc);
  1090. if (hdc == NULL)
  1091. {
  1092. DeleteObject(hbmp);
  1093. EndPaint(hWnd, &ps); // end of wnddc
  1094. wnddc = NULL;
  1095. return 0;
  1096. }
  1097. prevbmp = (HBITMAP)SelectObject(hdc, hbmp);
  1098. RegionI clip(&ps.rcPaint);
  1099. selectClipRgn(&clip);
  1100. srcwnd = basewnd;
  1101. return 1;
  1102. }
  1103. void *PaintBltCanvas::getBits()
  1104. {
  1105. return bits;
  1106. }
  1107. MemCanvas::MemCanvas()
  1108. {}
  1109. MemCanvas::~MemCanvas()
  1110. {
  1111. DeleteDC(hdc);
  1112. hdc = NULL;
  1113. }
  1114. int MemCanvas::createCompatible(Canvas *canvas)
  1115. {
  1116. ASSERT(canvas != NULL);
  1117. ASSERT(canvas->getHDC() != NULL);
  1118. hdc = CreateCompatibleDC(canvas->getHDC());
  1119. ASSERT(hdc != NULL);
  1120. srcwnd = canvas->getBaseWnd();
  1121. return 1;
  1122. }
  1123. DCCanvas::DCCanvas(HDC clone, BaseWnd *srcWnd)
  1124. {
  1125. if (clone != NULL) cloneDC(clone, srcWnd);
  1126. }
  1127. DCCanvas::~DCCanvas()
  1128. {
  1129. hdc = NULL;
  1130. }
  1131. int DCCanvas::cloneDC(HDC clone, BaseWnd *srcWnd)
  1132. {
  1133. ASSERT(clone != NULL);
  1134. hdc = clone;
  1135. srcwnd = srcWnd;
  1136. return 1;
  1137. }
  1138. SysCanvas::SysCanvas()
  1139. {
  1140. hdc = GetDC(NULL);
  1141. }
  1142. SysCanvas::~SysCanvas()
  1143. {
  1144. ReleaseDC(NULL, hdc);
  1145. hdc = NULL;
  1146. }
  1147. DCBltCanvas::DCBltCanvas()
  1148. {
  1149. origdc = NULL;
  1150. hbmp = prevbmp = NULL;
  1151. }
  1152. DCBltCanvas::~DCBltCanvas()
  1153. {
  1154. commitDC();
  1155. // kill the bitmap and its DC
  1156. SelectObject(hdc, prevbmp);
  1157. DeleteDC(hdc);
  1158. hdc = NULL;
  1159. DeleteObject(hbmp);
  1160. // don't kill origdc, it's been cloned
  1161. }
  1162. int DCBltCanvas::setOrigDC(HDC neworigdc)
  1163. {
  1164. // FG> allows custom draw on lists to be much faster
  1165. origdc = neworigdc;
  1166. return 1;
  1167. }
  1168. int DCBltCanvas::commitDC(void)
  1169. {
  1170. //FG
  1171. if (origdc)
  1172. {
  1173. RECT c;
  1174. if (GetClipBox(origdc, &c) == NULLREGION)
  1175. c = rect;
  1176. // shlap it down in its original spot
  1177. //GdiFlush();
  1178. BitBlt(origdc, c.left, c.top,
  1179. c.right - c.left, c.bottom - c.top, hdc, c.left-rect.left, c.top-rect.top, SRCCOPY);
  1180. }
  1181. return 1;
  1182. }
  1183. int DCBltCanvas::cloneDC(HDC clone, RECT *r, BaseWnd *srcWnd)
  1184. {
  1185. origdc = clone;
  1186. srcwnd = srcWnd;
  1187. ASSERT(r != NULL);
  1188. rect = *r;
  1189. #if 1
  1190. BITMAPINFO bmi;
  1191. ZeroMemory(&bmi, sizeof bmi);
  1192. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  1193. bmi.bmiHeader.biWidth = r->right - r->left;
  1194. bmi.bmiHeader.biHeight = -ABS(r->bottom - r->top);
  1195. bmi.bmiHeader.biPlanes = 1;
  1196. bmi.bmiHeader.biBitCount = 32;
  1197. bmi.bmiHeader.biCompression = BI_RGB;
  1198. bmi.bmiHeader.biSizeImage = 0;
  1199. bmi.bmiHeader.biXPelsPerMeter = 0;
  1200. bmi.bmiHeader.biYPelsPerMeter = 0;
  1201. bmi.bmiHeader.biClrUsed = 0;
  1202. bmi.bmiHeader.biClrImportant = 0;
  1203. hbmp = CreateDIBSection(origdc, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
  1204. width = bmi.bmiHeader.biWidth;
  1205. height = ABS(bmi.bmiHeader.biHeight);
  1206. pitch = width * 4;
  1207. #else
  1208. hbmp = CreateCompatibleBitmap(clone, r->right - r->left, r->bottom - r->top);
  1209. #endif
  1210. ASSERT(hbmp != NULL);
  1211. // create tha DC
  1212. hdc = CreateCompatibleDC(origdc);
  1213. prevbmp = (HBITMAP)SelectObject(hdc, hbmp);
  1214. // adjust their rect for them
  1215. r->right -= r->left;
  1216. r->left = 0;
  1217. r->bottom -= r->top;
  1218. r->top = 0;
  1219. return 1;
  1220. }
  1221. DCExBltCanvas::DCExBltCanvas(HWND hWnd, HRGN hrgnClip, DWORD flags) : hwnd(hWnd)
  1222. {
  1223. origdc = GetDCEx(hWnd, hrgnClip, flags);
  1224. RECT r;
  1225. GetWindowRect(hWnd, &r);
  1226. OffsetRect(&r, -r.left, -r.top);
  1227. cloneDC(origdc, &r);
  1228. }
  1229. DCExBltCanvas::~DCExBltCanvas()
  1230. {
  1231. commitDC();
  1232. ReleaseDC(hwnd, origdc);
  1233. origdc=0;
  1234. }
  1235. BaseCloneCanvas::BaseCloneCanvas(ifc_canvas *cloner)
  1236. {
  1237. if (cloner != NULL) clone(cloner);
  1238. }
  1239. int BaseCloneCanvas::clone(ifc_canvas *cloner)
  1240. {
  1241. ASSERTPR(hdc == NULL, "can't clone twice");
  1242. hdc = cloner->getHDC();
  1243. bits = cloner->getBits();
  1244. cloner->getDim(&width, &height, &pitch);
  1245. // srcwnd = cloner->getBaseWnd();
  1246. cloner->getOffsets(&xoffset, &yoffset);
  1247. canvasFontInfo.face = cloner->getTextFont(); // just copies the pointer so be careful
  1248. canvasFontInfo.pointSize = cloner->getTextSize();
  1249. canvasFontInfo.bold = cloner->getTextBold();
  1250. canvasFontInfo.opaque = !!cloner->getTextOpaque();
  1251. canvasFontInfo.underline = !!cloner->getTextUnderline();
  1252. canvasFontInfo.italic = !!cloner->getTextItalic();
  1253. canvasFontInfo.alignFlags = cloner->getTextAlign();
  1254. canvasFontInfo.color = cloner->getTextColor();
  1255. canvasFontInfo.bgColor = cloner->getTextBkColor();
  1256. return (hdc != NULL);
  1257. }
  1258. BaseCloneCanvas::~BaseCloneCanvas()
  1259. {
  1260. hdc = NULL;
  1261. }
  1262. DDSurfaceCanvas::DDSurfaceCanvas(LPDIRECTDRAWSURFACE surface, int w, int h)
  1263. {
  1264. surf = surface;
  1265. _w = w;
  1266. _h = h;
  1267. hdc = NULL;
  1268. bits = NULL;
  1269. }
  1270. DDSurfaceCanvas::~DDSurfaceCanvas()
  1271. {
  1272. if (isready())
  1273. exit();
  1274. }
  1275. int DDSurfaceCanvas::isready()
  1276. {
  1277. return bits != NULL;
  1278. }
  1279. void DDSurfaceCanvas::enter()
  1280. {
  1281. DDSURFACEDESC d = {sizeof(d), };
  1282. if ((surf->Lock(NULL, &d, DDLOCK_WAIT, NULL)) != DD_OK)
  1283. return ;
  1284. surf->GetDC(&hdc);
  1285. bits = d.lpSurface;
  1286. }
  1287. void DDSurfaceCanvas::exit()
  1288. {
  1289. surf->ReleaseDC(hdc);
  1290. surf->Unlock(bits);
  1291. bits = NULL;
  1292. hdc = NULL;
  1293. }
  1294. #endif//WIN32