graph.pp 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Florian Klaempfl
  4. This file implements the win32 gui support for the graph unit
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit Graph;
  12. interface
  13. uses
  14. windows;
  15. {$i graphh.inc}
  16. var
  17. { this procedure allows to hook keyboard messages }
  18. charmessagehandler : WndProc;
  19. { this procedure allows to hook mouse messages }
  20. mousemessagehandler : WndProc;
  21. { this procedure allows to wm_command messages }
  22. commandmessagehandler : WndProc;
  23. NotifyMessageHandler : WndProc;
  24. OnGraphWindowCreation : procedure;
  25. GraphWindow,ParentWindow : HWnd;
  26. // this allows direct drawing to the window
  27. bitmapdc : hdc;
  28. windc : hdc;
  29. const
  30. { predefined window style }
  31. { we shouldn't set CS_DBLCLKS here }
  32. { because most dos applications }
  33. { handle double clicks on it's own }
  34. graphwindowstyle : DWord = cs_hRedraw or cs_vRedraw;
  35. windowtitle : pchar = 'Graph window application';
  36. menu : hmenu = 0;
  37. icon : hicon = 0;
  38. drawtoscreen : boolean = true;
  39. drawtobitmap : boolean = true;
  40. // the graph window can be a child window, this allows to add toolbars
  41. // to the main window
  42. UseChildWindow : boolean = false;
  43. // this allows to specify an offset for the child child window
  44. ChildOffset : rect = (left:0;top:0;right:0;bottom:0);
  45. CONST
  46. m640x200x16 = VGALo;
  47. m640x400x16 = VGAMed;
  48. m640x480x16 = VGAHi;
  49. { VESA Specific video modes. }
  50. m320x200x32k = $10D;
  51. m320x200x64k = $10E;
  52. m640x400x256 = $100;
  53. m640x480x256 = $101;
  54. m640x480x32k = $110;
  55. m640x480x64k = $111;
  56. m800x600x16 = $102;
  57. m800x600x256 = $103;
  58. m800x600x32k = $113;
  59. m800x600x64k = $114;
  60. m1024x768x16 = $104;
  61. m1024x768x256 = $105;
  62. m1024x768x32k = $116;
  63. m1024x768x64k = $117;
  64. m1280x1024x16 = $106;
  65. m1280x1024x256 = $107;
  66. m1280x1024x32k = $119;
  67. m1280x1024x64k = $11A;
  68. { some extra modes which applies only to GUI }
  69. mLargestWindow16 = $f0;
  70. mLargestWindow256 = $f1;
  71. mLargestWindow32k = $f2;
  72. mLargestWindow64k = $f3;
  73. mLargestWindow16M = $f4;
  74. mMaximizedWindow16 = $f5;
  75. mMaximizedWindow256 = $f6;
  76. mMaximizedWindow32k = $f7;
  77. mMaximizedWindow64k = $f8;
  78. mMaximizedWindow16M = $f9;
  79. implementation
  80. uses
  81. strings;
  82. {
  83. Remarks:
  84. Colors in 16 color mode:
  85. ------------------------
  86. - the behavior of xor/or/and put isn't 100%:
  87. it is done using the RGB color getting from windows
  88. instead of the palette index!
  89. - palette operations aren't supported
  90. To solve these drawbacks, setpalette must be implemented
  91. by exchanging the colors in the DCs, further GetPaletteEntry
  92. must be used when doing xor/or/and operations
  93. }
  94. const
  95. InternalDriverName = 'WIN32GUI';
  96. {$i graph.inc}
  97. { used to create a file containing all calls to WM_PAINT
  98. WARNING this probably creates HUGE files PM }
  99. { $define DEBUG_WM_PAINT}
  100. var
  101. savedscreen : hbitmap;
  102. graphrunning : boolean;
  103. graphdrawing : tcriticalsection;
  104. pens : array[0..15] of HPEN;
  105. {$ifdef DEBUG_WM_PAINT}
  106. graphdebug : text;
  107. const
  108. wm_paint_count : longint = 0;
  109. var
  110. {$endif DEBUG_WM_PAINT}
  111. oldbitmap : hgdiobj;
  112. pal : ^rgbrec;
  113. // SavePtr : pointer; { we don't use that pointer }
  114. MessageThreadHandle : Handle;
  115. MessageThreadID : DWord;
  116. function GetPaletteEntry(r,g,b : word) : word;
  117. var
  118. dist,i,index,currentdist : longint;
  119. begin
  120. dist:=$7fffffff;
  121. index:=0;
  122. for i:=0 to maxcolors do
  123. begin
  124. currentdist:=abs(r-pal[i].red)+abs(g-pal[i].green)+
  125. abs(b-pal[i].blue);
  126. if currentdist<dist then
  127. begin
  128. index:=i;
  129. dist:=currentdist;
  130. if dist=0 then
  131. break;
  132. end;
  133. end;
  134. GetPaletteEntry:=index;
  135. end;
  136. procedure PutPixel16Win32GUI(x,y : smallint;pixel : word);
  137. var
  138. c : colorref;
  139. begin
  140. x:=x+startxviewport;
  141. y:=y+startyviewport;
  142. { convert to absolute coordinates and then verify clipping...}
  143. if clippixels then
  144. begin
  145. if (x<startxviewport) or (x>(startxviewport+viewwidth)) or
  146. (y<StartyViewPort) or (y>(startyviewport+viewheight)) then
  147. exit;
  148. end;
  149. if graphrunning then
  150. begin
  151. c:=RGB(pal[pixel].red,pal[pixel].green,pal[pixel].blue);
  152. EnterCriticalSection(graphdrawing);
  153. if drawtobitmap then
  154. SetPixelV(bitmapdc,x,y,c);
  155. if drawtoscreen then
  156. SetPixelV(windc,x,y,c);
  157. LeaveCriticalSection(graphdrawing);
  158. end;
  159. end;
  160. function GetPixel16Win32GUI(x,y : smallint) : word;
  161. var
  162. c : COLORREF;
  163. begin
  164. x:=x+startxviewport;
  165. y:=y+startyviewport;
  166. { convert to absolute coordinates and then verify clipping...}
  167. if clippixels then
  168. begin
  169. if (x<startxviewport) or (x>(startxviewport+viewwidth)) or
  170. (y<StartyViewPort) or (y>(startyviewport+viewheight)) then
  171. exit;
  172. end;
  173. if graphrunning then
  174. begin
  175. EnterCriticalSection(graphdrawing);
  176. c:=Windows.GetPixel(bitmapdc,x,y);
  177. LeaveCriticalSection(graphdrawing);
  178. GetPixel16Win32GUI:=GetPaletteEntry(GetRValue(c),GetGValue(c),GetBValue(c));
  179. end
  180. else
  181. begin
  182. _graphresult:=grerror;
  183. exit;
  184. end;
  185. end;
  186. procedure DirectPutPixel16Win32GUI(x,y : smallint);
  187. var
  188. col : longint;
  189. c,c2 : COLORREF;
  190. begin
  191. if graphrunning then
  192. begin
  193. EnterCriticalSection(graphdrawing);
  194. col:=CurrentColor;
  195. case currentwritemode of
  196. XorPut:
  197. Begin
  198. c2:=Windows.GetPixel(windc,x,y);
  199. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) xor c2;
  200. if drawtobitmap then
  201. SetPixelV(bitmapdc,x,y,c);
  202. if drawtoscreen then
  203. SetPixelV(windc,x,y,c);
  204. End;
  205. AndPut:
  206. Begin
  207. c2:=Windows.GetPixel(windc,x,y);
  208. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) and c2;
  209. if drawtobitmap then
  210. SetPixelV(bitmapdc,x,y,c);
  211. if drawtoscreen then
  212. SetPixelV(windc,x,y,c);
  213. End;
  214. OrPut:
  215. Begin
  216. c2:=Windows.GetPixel(windc,x,y);
  217. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) or c2;
  218. if drawtobitmap then
  219. SetPixelV(bitmapdc,x,y,c);
  220. if drawtoscreen then
  221. SetPixelV(windc,x,y,c);
  222. End
  223. else
  224. Begin
  225. If CurrentWriteMode<>NotPut Then
  226. col:=CurrentColor
  227. Else col := Not(CurrentColor);
  228. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  229. if drawtobitmap then
  230. SetPixelV(bitmapdc,x,y,c);
  231. if drawtoscreen then
  232. SetPixelV(windc,x,y,c);
  233. End
  234. end;
  235. LeaveCriticalSection(graphdrawing);
  236. end;
  237. end;
  238. var
  239. bitmapfontverticalcache : array[0..255] of HBITMAP;
  240. bitmapfonthorizoncache : array[0..255] of HBITMAP;
  241. procedure OutTextXYWin32GUI(x,y : smallint;const TextString : string);
  242. type
  243. Tpoint = record
  244. X,Y: smallint;
  245. end;
  246. var
  247. i,j,k,c : longint;
  248. xpos,ypos : longint;
  249. counter : longint;
  250. cnt1,cnt2 : smallint;
  251. cnt3,cnt4 : smallint;
  252. charsize : word;
  253. WriteMode : word;
  254. curX2, curY2, xpos2, ypos2, x2, y2: graph_float;
  255. oldvalues : linesettingstype;
  256. fontbitmap : TBitmapChar;
  257. chr : char;
  258. curx2i,cury2i,
  259. xpos2i,ypos2i : longint;
  260. charbitmap,oldcharbitmap : HBITMAP;
  261. chardc : HDC;
  262. color : longint;
  263. brushwin,oldbrushwin,brushbitmap,oldbrushbitmap : HBRUSH;
  264. bitmaprgn,winrgn : HRGN;
  265. begin
  266. { save current write mode }
  267. WriteMode := CurrentWriteMode;
  268. CurrentWriteMode := NormalPut;
  269. GetTextPosition(xpos,ypos,textstring);
  270. X:=X-XPos; Y:=Y+YPos;
  271. XPos:=X; YPos:=Y;
  272. CharSize := CurrentTextInfo.Charsize;
  273. if Currenttextinfo.font=DefaultFont then
  274. begin
  275. if CurrentTextInfo.direction=HorizDir then
  276. { Horizontal direction }
  277. begin
  278. if (x>viewwidth) or (y>viewheight) or
  279. (x<0) or (y<0) then
  280. begin
  281. CurrentWriteMode:=WriteMode;
  282. exit;
  283. end;
  284. EnterCriticalSection(graphdrawing);
  285. c:=length(textstring);
  286. chardc:=CreateCompatibleDC(windc);
  287. if currentcolor<>white then
  288. begin
  289. color:=RGB(pal[currentcolor].red,pal[currentcolor].green,
  290. pal[currentcolor].blue);
  291. if drawtoscreen then
  292. begin
  293. brushwin:=CreateSolidBrush(color);
  294. oldbrushwin:=SelectObject(windc,brushwin);
  295. end;
  296. if drawtobitmap then
  297. begin
  298. brushbitmap:=CreateSolidBrush(color);
  299. oldbrushbitmap:=SelectObject(bitmapdc,brushbitmap);
  300. end;
  301. end;
  302. inc(x,startxviewport);
  303. inc(y,startyviewport);
  304. { let windows do the clipping }
  305. if drawtobitmap then
  306. begin
  307. bitmaprgn:=CreateRectRgn(startxviewport,startyviewport,
  308. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  309. SelectClipRgn(bitmapdc,bitmaprgn);
  310. end;
  311. if drawtoscreen then
  312. begin
  313. winrgn:=CreateRectRgn(startxviewport,startyviewport,
  314. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  315. SelectClipRgn(windc,winrgn);
  316. end;
  317. for i:=0 to c-1 do
  318. begin
  319. xpos:=x+(i*8)*Charsize;
  320. if bitmapfonthorizoncache[byte(textstring[i+1])]=0 then
  321. begin
  322. charbitmap:=CreateCompatibleBitmap(windc,8,8);
  323. if charbitmap=0 then
  324. writeln('Bitmap konnte nicht erzeugt werden!');
  325. oldcharbitmap:=SelectObject(chardc,charbitmap);
  326. Fontbitmap:=TBitmapChar(DefaultFontData[textstring[i+1]]);
  327. for j:=0 to 7 do
  328. for k:=0 to 7 do
  329. if Fontbitmap[j,k]<>0 then
  330. SetPixelV(chardc,k,j,$ffffff)
  331. else
  332. SetPixelV(chardc,k,j,0);
  333. bitmapfonthorizoncache[byte(textstring[i+1])]:=charbitmap;
  334. SelectObject(chardc,oldcharbitmap);
  335. end;
  336. oldcharbitmap:=SelectObject(chardc,bitmapfonthorizoncache[byte(textstring[i+1])]);
  337. if CharSize=1 then
  338. begin
  339. if currentcolor=white then
  340. begin
  341. if drawtoscreen then
  342. BitBlt(windc,xpos,y,8,8,chardc,0,0,SRCPAINT);
  343. if drawtobitmap then
  344. BitBlt(bitmapdc,xpos,y,8,8,chardc,0,0,SRCPAINT);
  345. end
  346. else
  347. begin
  348. { could we do this with one pattern operation ?? }
  349. { we would need something like DSnaSPao }
  350. if drawtoscreen then
  351. begin
  352. // ROP $00220326=DSna
  353. BitBlt(windc,xpos,y,8,8,chardc,0,0,$00220326);
  354. // ROP $00EA02E9 = DPSao
  355. BitBlt(windc,xpos,y,8,8,chardc,0,0,$00EA02E9);
  356. end;
  357. if drawtobitmap then
  358. begin
  359. BitBlt(bitmapdc,xpos,y,8,8,chardc,0,0,$00220326);
  360. BitBlt(bitmapdc,xpos,y,8,8,chardc,0,0,$00EA02E9);
  361. end;
  362. end;
  363. end
  364. else
  365. begin
  366. if currentcolor=white then
  367. begin
  368. if drawtoscreen then
  369. StretchBlt(windc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,SRCPAINT);
  370. if drawtobitmap then
  371. StretchBlt(bitmapdc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,SRCPAINT);
  372. end
  373. else
  374. begin
  375. { could we do this with one pattern operation ?? }
  376. { we would need something like DSnaSPao }
  377. if drawtoscreen then
  378. begin
  379. // ROP $00220326=DSna
  380. StretchBlt(windc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,$00220326);
  381. // ROP $00EA02E9 = DPSao
  382. StretchBlt(windc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,$00EA02E9);
  383. end;
  384. if drawtobitmap then
  385. begin
  386. StretchBlt(bitmapdc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,$00220326);
  387. StretchBlt(bitmapdc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,$00EA02E9);
  388. end;
  389. end;
  390. end;
  391. SelectObject(chardc,oldcharbitmap);
  392. end;
  393. if currentcolor<>white then
  394. begin
  395. if drawtoscreen then
  396. begin
  397. SelectObject(windc,oldbrushwin);
  398. DeleteObject(brushwin);
  399. end;
  400. if drawtobitmap then
  401. begin
  402. SelectObject(bitmapdc,oldbrushbitmap);
  403. DeleteObject(brushbitmap);
  404. end;
  405. end;
  406. { release clip regions }
  407. if drawtobitmap then
  408. begin
  409. SelectClipRgn(bitmapdc,0);
  410. DeleteObject(bitmaprgn);
  411. end;
  412. if drawtoscreen then
  413. begin
  414. SelectClipRgn(windc,0);
  415. DeleteObject(winrgn);
  416. end;
  417. DeleteDC(chardc);
  418. LeaveCriticalSection(graphdrawing);
  419. end
  420. else
  421. { Vertical direction }
  422. begin
  423. if (x>viewwidth) or (y>viewheight) or
  424. (x<0) or (y<0) then
  425. begin
  426. CurrentWriteMode:=WriteMode;
  427. exit;
  428. end;
  429. EnterCriticalSection(graphdrawing);
  430. c:=length(textstring);
  431. chardc:=CreateCompatibleDC(windc);
  432. if currentcolor<>white then
  433. begin
  434. color:=RGB(pal[currentcolor].red,pal[currentcolor].green,
  435. pal[currentcolor].blue);
  436. if drawtoscreen then
  437. begin
  438. brushwin:=CreateSolidBrush(color);
  439. oldbrushwin:=SelectObject(windc,brushwin);
  440. end;
  441. if drawtobitmap then
  442. begin
  443. brushbitmap:=CreateSolidBrush(color);
  444. oldbrushbitmap:=SelectObject(bitmapdc,brushbitmap);
  445. end;
  446. end;
  447. inc(x,startxviewport);
  448. inc(y,startyviewport);
  449. { let windows do the clipping }
  450. if drawtoscreen then
  451. begin
  452. winrgn:=CreateRectRgn(startxviewport,startyviewport,
  453. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  454. SelectClipRgn(windc,winrgn);
  455. end;
  456. if drawtobitmap then
  457. begin
  458. bitmaprgn:=CreateRectRgn(startxviewport,startyviewport,
  459. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  460. SelectClipRgn(bitmapdc,bitmaprgn);
  461. end;
  462. for i:=0 to c-1 do
  463. begin
  464. ypos:=y+1-((i+1)*8)*CharSize;
  465. if bitmapfontverticalcache[byte(textstring[i+1])]=0 then
  466. begin
  467. charbitmap:=CreateCompatibleBitmap(windc,8,8);
  468. if charbitmap=0 then
  469. writeln('Bitmap konnte nicht erzeugt werden!');
  470. oldcharbitmap:=SelectObject(chardc,charbitmap);
  471. Fontbitmap:=TBitmapChar(DefaultFontData[textstring[i+1]]);
  472. for j:=0 to 7 do
  473. for k:=0 to 7 do
  474. if Fontbitmap[j,k]<>0 then
  475. SetPixelV(chardc,j,7-k,$ffffff)
  476. else
  477. SetPixelV(chardc,j,7-k,0);
  478. bitmapfontverticalcache[byte(textstring[i+1])]:=charbitmap;
  479. SelectObject(chardc,oldcharbitmap);
  480. end;
  481. oldcharbitmap:=SelectObject(chardc,bitmapfontverticalcache[byte(textstring[i+1])]);
  482. if CharSize=1 then
  483. begin
  484. if currentcolor=white then
  485. begin
  486. if drawtoscreen then
  487. BitBlt(windc,x,ypos,8,8,chardc,0,0,SRCPAINT);
  488. if drawtobitmap then
  489. BitBlt(bitmapdc,x,ypos,8,8,chardc,0,0,SRCPAINT);
  490. end
  491. else
  492. begin
  493. { could we do this with one pattern operation ?? }
  494. { we would need something like DSnaSPao }
  495. if drawtoscreen then
  496. begin
  497. // ROP $00220326=DSna
  498. BitBlt(windc,x,ypos,8,8,chardc,0,0,$00220326);
  499. // ROP $00EA02E9 = DPSao
  500. BitBlt(windc,x,ypos,8,8,chardc,0,0,$00EA02E9);
  501. end;
  502. if drawtobitmap then
  503. begin
  504. BitBlt(bitmapdc,x,ypos,8,8,chardc,0,0,$00220326);
  505. BitBlt(bitmapdc,x,ypos,8,8,chardc,0,0,$00EA02E9);
  506. end;
  507. end;
  508. end
  509. else
  510. begin
  511. if currentcolor=white then
  512. begin
  513. if drawtoscreen then
  514. StretchBlt(windc,x,ypos,8*charsize,8*charsize,chardc,0,0,8,8,SRCPAINT);
  515. if drawtobitmap then
  516. StretchBlt(bitmapdc,x,ypos,8*charsize,8*charsize,chardc,0,0,8,8,SRCPAINT);
  517. end
  518. else
  519. begin
  520. { could we do this with one pattern operation ?? }
  521. { we would need something like DSnaSPao }
  522. if drawtoscreen then
  523. begin
  524. // ROP $00220326=DSna
  525. StretchBlt(windc,x,ypos,8*charsize,8*charsize,chardc,0,0,8,8,$00220326);
  526. // ROP $00EA02E9 = DPSao
  527. StretchBlt(windc,x,ypos,8*charsize,8*charsize,chardc,0,0,8,8,$00EA02E9);
  528. end;
  529. if drawtobitmap then
  530. begin
  531. StretchBlt(bitmapdc,x,ypos,8*charsize,8*charsize,chardc,0,0,8,8,$00220326);
  532. StretchBlt(bitmapdc,x,ypos,8*charsize,8*charsize,chardc,0,0,8,8,$00EA02E9);
  533. end;
  534. end;
  535. end;
  536. SelectObject(chardc,oldcharbitmap);
  537. end;
  538. if currentcolor<>white then
  539. begin
  540. if drawtoscreen then
  541. begin
  542. SelectObject(windc,oldbrushwin);
  543. DeleteObject(brushwin);
  544. end;
  545. if drawtobitmap then
  546. begin
  547. SelectObject(bitmapdc,oldbrushbitmap);
  548. DeleteObject(brushbitmap);
  549. end;
  550. end;
  551. { release clip regions }
  552. if drawtoscreen then
  553. begin
  554. SelectClipRgn(windc,0);
  555. DeleteObject(winrgn);
  556. end;
  557. if drawtobitmap then
  558. begin
  559. SelectClipRgn(bitmapdc,0);
  560. DeleteObject(bitmaprgn);
  561. end;
  562. DeleteDC(chardc);
  563. LeaveCriticalSection(graphdrawing);
  564. end;
  565. end else
  566. { This is a stroked font which is already loaded into memory }
  567. begin
  568. getlinesettings(oldvalues);
  569. { reset line style to defaults }
  570. setlinestyle(solidln,oldvalues.pattern,normwidth);
  571. if Currenttextinfo.direction=vertdir then
  572. xpos:=xpos + Textheight(textstring);
  573. CurX2:=xpos; xpos2 := curX2; x2 := xpos2;
  574. CurY2:=ypos; ypos2 := curY2; y2 := ypos2;
  575. { x:=xpos; y:=ypos;}
  576. for i:=1 to length(textstring) do
  577. begin
  578. c:=byte(textstring[i]);
  579. { Stroke_Count[c] := }
  580. unpack( fonts[CurrentTextInfo.font].instr,
  581. fonts[CurrentTextInfo.font].Offsets[c], Strokes );
  582. counter:=0;
  583. while true do
  584. begin
  585. if CurrentTextInfo.direction=VertDir then
  586. begin
  587. xpos2:=x2-(Strokes[counter].Y*CurrentYRatio);
  588. ypos2:=y2-(Strokes[counter].X*CurrentXRatio);
  589. end
  590. else
  591. begin
  592. xpos2:=x2+(Strokes[counter].X*CurrentXRatio) ;
  593. ypos2:=y2-(Strokes[counter].Y*CurrentYRatio) ;
  594. end;
  595. case opcodes(Strokes[counter].opcode) of
  596. _END_OF_CHAR: break;
  597. _DO_SCAN: begin
  598. { Currently unsupported };
  599. end;
  600. _MOVE : Begin
  601. CurX2 := XPos2;
  602. CurY2 := YPos2;
  603. end;
  604. _DRAW: Begin
  605. curx2i:=trunc(CurX2);
  606. cury2i:=trunc(CurY2);
  607. xpos2i:=trunc(xpos2);
  608. ypos2i:=trunc(ypos2);
  609. { this optimization doesn't matter that much
  610. if (curx2i=xpos2i) then
  611. begin
  612. if (cury2i=ypos2i) then
  613. putpixel(curx2i,cury2i,currentcolor)
  614. else if (cury2i+1=ypos2i) or
  615. (cury2i=ypos2i+1) then
  616. begin
  617. putpixel(curx2i,cury2i,currentcolor);
  618. putpixel(curx2i,ypos2i,currentcolor);
  619. end
  620. else
  621. Line(curx2i,cury2i,xpos2i,ypos2i);
  622. end
  623. else if (cury2i=ypos2i) then
  624. begin
  625. if (curx2i+1=xpos2i) or
  626. (curx2i=xpos2i+1) then
  627. begin
  628. putpixel(curx2i,cury2i,currentcolor);
  629. putpixel(xpos2i,cury2i,currentcolor);
  630. end
  631. else
  632. Line(curx2i,cury2i,xpos2i,ypos2i);
  633. end
  634. else
  635. }
  636. Line(curx2i,cury2i,xpos2i,ypos2i);
  637. CurX2:=xpos2;
  638. CurY2:=ypos2;
  639. end;
  640. else
  641. Begin
  642. end;
  643. end;
  644. Inc(counter);
  645. end; { end while }
  646. if Currenttextinfo.direction=VertDir then
  647. y2:=y2-(byte(fonts[CurrenttextInfo.font].widths[c])*CurrentXRatio)
  648. else
  649. x2:=x2+(byte(fonts[Currenttextinfo.font].widths[c])*CurrentXRatio);
  650. end;
  651. setlinestyle( oldvalues.linestyle, oldvalues.pattern, oldvalues.thickness);
  652. end;
  653. { restore write mode }
  654. CurrentWriteMode := WriteMode;
  655. end;
  656. procedure HLine16Win32GUI(x,x2,y: smallint);
  657. var
  658. c,c2 : COLORREF;
  659. col,i : longint;
  660. oldpen,pen : HPEN;
  661. Begin
  662. if graphrunning then
  663. begin
  664. { must we swap the values? }
  665. if x>x2 then
  666. Begin
  667. x:=x xor x2;
  668. x2:=x xor x2;
  669. x:=x xor x2;
  670. end;
  671. if ClipPixels then
  672. begin
  673. if (x>ViewWidth) or (y<0) or (y>ViewHeight) or (x2<0) then
  674. exit;
  675. if x<0 then
  676. x:=0;
  677. if x2>ViewWidth then
  678. x2:=ViewWidth;
  679. end;
  680. X:=X+StartXViewPort;
  681. X2:=X2+StartXViewPort;
  682. Y:=Y+StartYViewPort;
  683. Case CurrentWriteMode of
  684. AndPut:
  685. Begin
  686. EnterCriticalSection(graphdrawing);
  687. col:=CurrentColor;
  688. for i:=x to x2 do
  689. begin
  690. c2:=Windows.GetPixel(windc,i,y);
  691. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) and c2;
  692. if drawtobitmap then
  693. SetPixelV(bitmapdc,i,y,c);
  694. if drawtoscreen then
  695. SetPixelV(windc,i,y,c);
  696. end;
  697. LeaveCriticalSection(graphdrawing);
  698. End;
  699. XorPut:
  700. Begin
  701. EnterCriticalSection(graphdrawing);
  702. col:=CurrentColor;
  703. for i:=x to x2 do
  704. begin
  705. c2:=Windows.GetPixel(windc,i,y);
  706. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) xor c2;
  707. if drawtobitmap then
  708. SetPixelV(bitmapdc,i,y,c);
  709. if drawtoscreen then
  710. SetPixelV(windc,i,y,c);
  711. end;
  712. LeaveCriticalSection(graphdrawing);
  713. End;
  714. OrPut:
  715. Begin
  716. EnterCriticalSection(graphdrawing);
  717. col:=CurrentColor;
  718. for i:=x to x2 do
  719. begin
  720. c2:=Windows.GetPixel(windc,i,y);
  721. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) or c2;
  722. if drawtobitmap then
  723. SetPixelV(bitmapdc,i,y,c);
  724. if drawtoscreen then
  725. SetPixelV(windc,i,y,c);
  726. end;
  727. LeaveCriticalSection(graphdrawing);
  728. End
  729. Else
  730. Begin
  731. If CurrentWriteMode<>NotPut Then
  732. col:=CurrentColor
  733. Else col:=Not(CurrentColor);
  734. EnterCriticalSection(graphdrawing);
  735. if x2-x<=2 then
  736. begin
  737. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  738. for x := x to x2 do
  739. begin
  740. if drawtobitmap then
  741. SetPixelV(bitmapdc,x,y,c);
  742. if drawtoscreen then
  743. SetPixelV(windc,x,y,c);
  744. end;
  745. end
  746. else
  747. begin
  748. if (col>=0) and (col<=high(pens)) then
  749. begin
  750. if pens[col]=0 then
  751. begin
  752. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  753. pens[col]:=CreatePen(PS_SOLID,1,c);
  754. end;
  755. pen:=pens[col];
  756. end
  757. else
  758. begin
  759. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  760. pen:=CreatePen(PS_SOLID,1,c);
  761. end;
  762. if drawtobitmap then
  763. begin
  764. oldpen:=SelectObject(bitmapdc,pen);
  765. Windows.MoveToEx(bitmapdc,x,y,nil);
  766. Windows.LineTo(bitmapdc,x2+1,y);
  767. SelectObject(bitmapdc,oldpen);
  768. end;
  769. if drawtoscreen then
  770. begin
  771. oldpen:=SelectObject(windc,pen);
  772. Windows.MoveToEx(windc,x,y,nil);
  773. Windows.LineTo(windc,x2+1,y);
  774. SelectObject(windc,oldpen);
  775. end;
  776. if (col<0) or (col>high(pens)) then
  777. DeleteObject(pen);
  778. end;
  779. LeaveCriticalSection(graphdrawing);
  780. End;
  781. End;
  782. end;
  783. end;
  784. procedure VLine16Win32GUI(x,y,y2: smallint); {$ifndef fpc}far;{$endif fpc}
  785. var
  786. ytmp: smallint;
  787. col,c : longint;
  788. oldpen,pen : HPEN;
  789. Begin
  790. { must we swap the values? }
  791. if y >= y2 then
  792. Begin
  793. ytmp := y2;
  794. y2 := y;
  795. y:= ytmp;
  796. end;
  797. if ClipPixels then
  798. begin
  799. if (x>ViewWidth) or (x<0) or (y>ViewHeight) or (y2<0) then
  800. exit;
  801. if y<0 then
  802. y:=0;
  803. if y2>ViewHeight then
  804. y2:=ViewHeight;
  805. end;
  806. { First convert to global coordinates }
  807. X := X + StartXViewPort;
  808. Y2 := Y2 + StartYViewPort;
  809. Y := Y + StartYViewPort;
  810. if currentwritemode=normalput then
  811. begin
  812. col:=CurrentColor;
  813. EnterCriticalSection(graphdrawing);
  814. if y2-y<=2 then
  815. begin
  816. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  817. for y := y to y2 do
  818. begin
  819. if drawtobitmap then
  820. SetPixelV(bitmapdc,x,y,c);
  821. if drawtoscreen then
  822. SetPixelV(windc,x,y,c);
  823. end;
  824. end
  825. else
  826. begin
  827. if (col>=0) and (col<=high(pens)) then
  828. begin
  829. if pens[col]=0 then
  830. begin
  831. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  832. pens[col]:=CreatePen(PS_SOLID,1,c);
  833. end;
  834. pen:=pens[col];
  835. end
  836. else
  837. begin
  838. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  839. pen:=CreatePen(PS_SOLID,1,c);
  840. end;
  841. if drawtobitmap then
  842. begin
  843. oldpen:=SelectObject(bitmapdc,pen);
  844. Windows.MoveToEx(bitmapdc,x,y,nil);
  845. Windows.LineTo(bitmapdc,x,y2+1);
  846. SelectObject(bitmapdc,oldpen);
  847. end;
  848. if drawtoscreen then
  849. begin
  850. oldpen:=SelectObject(windc,pen);
  851. Windows.MoveToEx(windc,x,y,nil);
  852. Windows.LineTo(windc,x,y2+1);
  853. SelectObject(windc,oldpen);
  854. end;
  855. if (col<0) or (col>high(pens)) then
  856. DeleteObject(pen);
  857. end;
  858. LeaveCriticalSection(graphdrawing);
  859. end
  860. else
  861. for y := y to y2 do Directputpixel(x,y)
  862. End;
  863. procedure Circle16Win32GUI(X, Y: smallint; Radius:Word);
  864. var
  865. bitmaprgn,winrgn : HRGN;
  866. col,c : longint;
  867. oldpen,pen : HPEN;
  868. OriginalArcInfo: ArcCoordsType;
  869. OldWriteMode: word;
  870. begin
  871. if (Radius = 0) then
  872. Exit;
  873. if (Radius = 1) then
  874. begin
  875. { only normal put mode is supported by a call to PutPixel }
  876. PutPixel(X, Y, CurrentColor);
  877. Exit;
  878. end;
  879. if (Radius = 2) then
  880. begin
  881. { only normal put mode is supported by a call to PutPixel }
  882. PutPixel(X-1, Y, CurrentColor);
  883. PutPixel(X+1, Y, CurrentColor);
  884. PutPixel(X, Y-1, CurrentColor);
  885. PutPixel(X, Y+1, CurrentColor);
  886. Exit;
  887. end;
  888. if LineInfo.Thickness = Normwidth then
  889. begin
  890. EnterCriticalSection(graphdrawing);
  891. { let windows do the clipping }
  892. if drawtobitmap then
  893. begin
  894. bitmaprgn:=CreateRectRgn(startxviewport,startyviewport,
  895. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  896. SelectClipRgn(bitmapdc,bitmaprgn);
  897. end;
  898. if drawtoscreen then
  899. begin
  900. winrgn:=CreateRectRgn(startxviewport,startyviewport,
  901. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  902. SelectClipRgn(windc,winrgn);
  903. end;
  904. inc(x,StartXViewPort);
  905. inc(y,StartYViewPort);
  906. col:=CurrentColor;
  907. if (col>=0) and (col<=high(pens)) then
  908. begin
  909. if pens[col]=0 then
  910. begin
  911. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  912. pens[col]:=CreatePen(PS_SOLID,1,c);
  913. end;
  914. pen:=pens[col];
  915. end
  916. else
  917. begin
  918. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  919. pen:=CreatePen(PS_SOLID,1,c);
  920. end;
  921. if drawtobitmap then
  922. begin
  923. oldpen:=SelectObject(bitmapdc,pen);
  924. windows.arc(bitmapdc,x-radius,y-radius,x+radius,y+radius,
  925. x,y-radius,x,y-radius);
  926. SelectObject(bitmapdc,oldpen);
  927. end;
  928. if drawtoscreen then
  929. begin
  930. oldpen:=SelectObject(windc,pen);
  931. windows.arc(windc,x-radius,y-radius,x+radius,y+radius,
  932. x,y-radius,x,y-radius);
  933. SelectObject(windc,oldpen);
  934. end;
  935. if (col<0) or (col>high(pens)) then
  936. DeleteObject(pen);
  937. { release clip regions }
  938. if drawtoscreen then
  939. begin
  940. SelectClipRgn(windc,0);
  941. DeleteObject(winrgn);
  942. end;
  943. if drawtobitmap then
  944. begin
  945. SelectClipRgn(bitmapdc,0);
  946. DeleteObject(bitmaprgn);
  947. end;
  948. LeaveCriticalSection(graphdrawing);
  949. end
  950. else
  951. begin
  952. { save state of arc information }
  953. { because it is not needed for }
  954. { a circle call. }
  955. move(ArcCall,OriginalArcInfo, sizeof(ArcCall));
  956. InternalEllipse(X,Y,Radius,Radius,0,360,{$ifdef fpc}@{$endif}DummyPatternLine);
  957. { restore arc information }
  958. move(OriginalArcInfo, ArcCall,sizeof(ArcCall));
  959. end;
  960. end;
  961. {
  962. Procedure PutImageWin32GUI(X,Y: smallint; var Bitmap; BitBlt: Word); {$ifndef fpc}far;{$endif fpc}
  963. type
  964. pt = array[0..$fffffff] of word;
  965. ptw = array[0..2] of longint;
  966. var
  967. k: longint;
  968. oldCurrentColor: word;
  969. oldCurrentWriteMode, i, j, y1, x1, deltaX, deltaX1, deltaY: smallint;
  970. Begin
  971. {$ifdef logging}
  972. LogLn('putImage at ('+strf(x)+','+strf(y)+') with width '+strf(ptw(Bitmap)[0])+
  973. ' and height '+strf(ptw(Bitmap)[1]));
  974. deltaY := 0;
  975. {$endif logging}
  976. inc(x,startXViewPort);
  977. inc(y,startYViewPort);
  978. x1 := ptw(Bitmap)[0]+x; { get width and adjust end coordinate accordingly }
  979. y1 := ptw(Bitmap)[1]+y; { get height and adjust end coordinate accordingly }
  980. deltaX := 0;
  981. deltaX1 := 0;
  982. k := 3 * sizeOf(Longint) div sizeOf(Word); { Three reserved longs at start of bitmap }
  983. { check which part of the image is in the viewport }
  984. if clipPixels then
  985. begin
  986. if y < startYViewPort then
  987. begin
  988. deltaY := startYViewPort - y;
  989. inc(k,(x1-x+1)*deltaY);
  990. y := startYViewPort;
  991. end;
  992. if y1 > startYViewPort+viewHeight then
  993. y1 := startYViewPort+viewHeight;
  994. if x < startXViewPort then
  995. begin
  996. deltaX := startXViewPort-x;
  997. x := startXViewPort;
  998. end;
  999. if x1 > startXViewPort + viewWidth then
  1000. begin
  1001. deltaX1 := x1 - (startXViewPort + viewWidth);
  1002. x1 := startXViewPort + viewWidth;
  1003. end;
  1004. end;
  1005. {$ifdef logging}
  1006. LogLn('deltax: '+strf(deltax)+', deltax1: '+strf(deltax1)+',deltay: '+strf(deltay));
  1007. {$endif logging}
  1008. case bitBlt of
  1009. end;
  1010. oldCurrentColor := currentColor;
  1011. oldCurrentWriteMode := currentWriteMode;
  1012. currentWriteMode := bitBlt;
  1013. for j:=Y to Y1 do
  1014. Begin
  1015. inc(k,deltaX);
  1016. for i:=X to X1 do
  1017. begin
  1018. currentColor := pt(bitmap)[k];
  1019. directPutPixel(i,j);
  1020. inc(k);
  1021. end;
  1022. inc(k,deltaX1);
  1023. end;
  1024. currentWriteMode := oldCurrentWriteMode;
  1025. currentColor := oldCurrentColor;
  1026. end;
  1027. }
  1028. procedure SetRGBPaletteWin32GUI(colorNum,redValue,greenvalue,
  1029. bluevalue : smallint);
  1030. begin
  1031. if directcolor or (colornum<0) or (colornum>=maxcolor) then
  1032. begin
  1033. _graphresult:=grerror;
  1034. exit;
  1035. end;
  1036. pal[colorNum].red:=redValue;
  1037. pal[colorNum].green:=greenValue;
  1038. pal[colorNum].blue:=blueValue;
  1039. if (colorNum>=0) and (colorNum<=high(pens)) and (pens[colorNum]<>0) then
  1040. begin
  1041. DeleteObject(pens[colorNum]);
  1042. pens[colorNum]:=0;
  1043. end;
  1044. end;
  1045. procedure GetRGBPaletteWin32GUI(colorNum : smallint;
  1046. var redValue,greenvalue,bluevalue : smallint);
  1047. begin
  1048. if directcolor or (colornum<0) or (colornum>=maxcolor) then
  1049. begin
  1050. _graphresult:=grerror;
  1051. exit;
  1052. end;
  1053. redValue:=pal[colorNum].red;
  1054. greenValue:=pal[colorNum].green;
  1055. blueValue:=pal[colorNum].blue;
  1056. end;
  1057. procedure savestate;
  1058. begin
  1059. end;
  1060. procedure restorestate;
  1061. begin
  1062. end;
  1063. function WindowProcGraph(Window: HWnd; AMessage:UInt; WParam : WParam;
  1064. LParam: LParam): Longint; stdcall;
  1065. var
  1066. dc : hdc;
  1067. ps : paintstruct;
  1068. r : rect;
  1069. oldbrush : hbrush;
  1070. oldpen : hpen;
  1071. i : longint;
  1072. begin
  1073. WindowProcGraph := 0;
  1074. case AMessage of
  1075. wm_lbuttondown,
  1076. wm_rbuttondown,
  1077. wm_mbuttondown,
  1078. wm_lbuttonup,
  1079. wm_rbuttonup,
  1080. wm_mbuttonup,
  1081. wm_lbuttondblclk,
  1082. wm_rbuttondblclk,
  1083. wm_mbuttondblclk:
  1084. {
  1085. This leads to problem, i.e. the menu etc doesn't work any longer
  1086. wm_nclbuttondown,
  1087. wm_ncrbuttondown,
  1088. wm_ncmbuttondown,
  1089. wm_nclbuttonup,
  1090. wm_ncrbuttonup,
  1091. wm_ncmbuttonup,
  1092. wm_nclbuttondblclk,
  1093. wm_ncrbuttondblclk,
  1094. wm_ncmbuttondblclk:
  1095. }
  1096. begin
  1097. if assigned(mousemessagehandler) then
  1098. WindowProcGraph:=mousemessagehandler(window,amessage,wparam,lparam);
  1099. end;
  1100. wm_notify:
  1101. begin
  1102. if assigned(notifymessagehandler) then
  1103. WindowProcGraph:=notifymessagehandler(window,amessage,wparam,lparam);
  1104. end;
  1105. wm_command:
  1106. if assigned(commandmessagehandler) then
  1107. WindowProcGraph:=commandmessagehandler(window,amessage,wparam,lparam);
  1108. wm_keydown,
  1109. wm_keyup,
  1110. wm_char:
  1111. begin
  1112. if assigned(charmessagehandler) then
  1113. WindowProcGraph:=charmessagehandler(window,amessage,wparam,lparam);
  1114. end;
  1115. wm_paint:
  1116. begin
  1117. {$ifdef DEBUG_WM_PAINT}
  1118. inc(wm_paint_count);
  1119. {$endif DEBUG_WM_PAINT}
  1120. {$ifdef DEBUGCHILDS}
  1121. writeln('Start child painting');
  1122. {$endif DEBUGCHILDS}
  1123. if not GetUpdateRect(Window,@r,false) then
  1124. exit;
  1125. EnterCriticalSection(graphdrawing);
  1126. graphrunning:=true;
  1127. dc:=BeginPaint(Window,@ps);
  1128. {$ifdef DEBUG_WM_PAINT}
  1129. Writeln(graphdebug,'WM_PAINT in ((',r.left,',',r.top,
  1130. '),(',r.right,',',r.bottom,'))');
  1131. {$endif def DEBUG_WM_PAINT}
  1132. if graphrunning then
  1133. {BitBlt(dc,0,0,maxx+1,maxy+1,bitmapdc,0,0,SRCCOPY);}
  1134. BitBlt(dc,r.left,r.top,r.right-r.left+1,r.bottom-r.top+1,bitmapdc,r.left,r.top,SRCCOPY);
  1135. EndPaint(Window,ps);
  1136. LeaveCriticalSection(graphdrawing);
  1137. Exit;
  1138. end;
  1139. wm_create:
  1140. begin
  1141. {$ifdef DEBUG_WM_PAINT}
  1142. assign(graphdebug,'wingraph.log');
  1143. rewrite(graphdebug);
  1144. {$endif DEBUG_WM_PAINT}
  1145. {$ifdef DEBUGCHILDS}
  1146. writeln('Creating window (HWND: ',window,')... ');
  1147. {$endif DEBUGCHILDS}
  1148. GraphWindow:=window;
  1149. EnterCriticalSection(graphdrawing);
  1150. dc:=GetDC(window);
  1151. {$ifdef DEBUGCHILDS}
  1152. writeln('Window DC: ',dc);
  1153. {$endif DEBUGCHILDS}
  1154. bitmapdc:=CreateCompatibleDC(dc);
  1155. savedscreen:=CreateCompatibleBitmap(dc,maxx+1,maxy+1);
  1156. ReleaseDC(window,dc);
  1157. oldbitmap:=SelectObject(bitmapdc,savedscreen);
  1158. windc:=GetDC(window);
  1159. // clear everything
  1160. oldpen:=SelectObject(bitmapdc,GetStockObject(BLACK_PEN));
  1161. oldbrush:=SelectObject(bitmapdc,GetStockObject(BLACK_BRUSH));
  1162. Windows.Rectangle(bitmapdc,0,0,maxx,maxy);
  1163. SelectObject(bitmapdc,oldpen);
  1164. SelectObject(bitmapdc,oldbrush);
  1165. // ... the window too
  1166. oldpen:=SelectObject(windc,GetStockObject(BLACK_PEN));
  1167. oldbrush:=SelectObject(windc,GetStockObject(BLACK_BRUSH));
  1168. Windows.Rectangle(windc,0,0,maxx,maxy);
  1169. SelectObject(windc,oldpen);
  1170. SelectObject(windc,oldbrush);
  1171. // clear font cache
  1172. fillchar(bitmapfonthorizoncache,sizeof(bitmapfonthorizoncache),0);
  1173. fillchar(bitmapfontverticalcache,sizeof(bitmapfontverticalcache),0);
  1174. // clear predefined pens
  1175. fillchar(pens,sizeof(pens),0);
  1176. if assigned(OnGraphWindowCreation) then
  1177. OnGraphWindowCreation;
  1178. LeaveCriticalSection(graphdrawing);
  1179. {$ifdef DEBUGCHILDS}
  1180. writeln('done');
  1181. GetClientRect(window,@r);
  1182. writeln('Window size: ',r.right,',',r.bottom);
  1183. {$endif DEBUGCHILDS}
  1184. end;
  1185. wm_Destroy:
  1186. begin
  1187. EnterCriticalSection(graphdrawing);
  1188. graphrunning:=false;
  1189. ReleaseDC(GraphWindow,windc);
  1190. SelectObject(bitmapdc,oldbitmap);
  1191. DeleteObject(savedscreen);
  1192. DeleteDC(bitmapdc);
  1193. // release font cache
  1194. for i:=0 to 255 do
  1195. if bitmapfonthorizoncache[i]<>0 then
  1196. DeleteObject(bitmapfonthorizoncache[i]);
  1197. for i:=0 to 255 do
  1198. if bitmapfontverticalcache[i]<>0 then
  1199. DeleteObject(bitmapfontverticalcache[i]);
  1200. for i:=0 to high(pens) do
  1201. if pens[i]<>0 then
  1202. DeleteObject(pens[i]);
  1203. LeaveCriticalSection(graphdrawing);
  1204. {$ifdef DEBUG_WM_PAINT}
  1205. close(graphdebug);
  1206. {$endif DEBUG_WM_PAINT}
  1207. PostQuitMessage(0);
  1208. Exit;
  1209. end
  1210. else
  1211. WindowProcGraph := DefWindowProc(Window, AMessage, WParam, LParam);
  1212. end;
  1213. end;
  1214. function WindowProcParent(Window: HWnd; AMessage:UInt; WParam : WParam;
  1215. LParam: LParam): Longint; stdcall;
  1216. begin
  1217. WindowProcParent := 0;
  1218. case AMessage of
  1219. wm_keydown,
  1220. wm_keyup,
  1221. wm_char:
  1222. begin
  1223. if assigned(charmessagehandler) then
  1224. WindowProcParent:=charmessagehandler(window,amessage,wparam,lparam);
  1225. end;
  1226. wm_notify:
  1227. begin
  1228. if assigned(notifymessagehandler) then
  1229. WindowProcParent:=notifymessagehandler(window,amessage,wparam,lparam);
  1230. end;
  1231. wm_command:
  1232. if assigned(commandmessagehandler) then
  1233. WindowProcParent:=commandmessagehandler(window,amessage,wparam,lparam);
  1234. else
  1235. WindowProcParent := DefWindowProc(Window, AMessage, WParam, LParam);
  1236. end;
  1237. end;
  1238. function WinRegister: Boolean;
  1239. var
  1240. WindowClass: WndClass;
  1241. begin
  1242. WindowClass.Style := graphwindowstyle;
  1243. WindowClass.lpfnWndProc := WndProc(@WindowProcGraph);
  1244. WindowClass.cbClsExtra := 0;
  1245. WindowClass.cbWndExtra := 0;
  1246. WindowClass.hInstance := system.MainInstance;
  1247. if icon<>0 then
  1248. WindowClass.hIcon := icon
  1249. else
  1250. WindowClass.hIcon := LoadIcon(0, idi_Application);
  1251. WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  1252. WindowClass.hbrBackground := GetStockObject(BLACK_BRUSH);
  1253. if menu<>0 then
  1254. WindowClass.lpszMenuName := MAKEINTRESOURCE(menu)
  1255. else
  1256. WindowClass.lpszMenuName := nil;
  1257. WindowClass.lpszClassName := 'FPCGraphWindow';
  1258. winregister:=RegisterClass(WindowClass) <> 0;
  1259. end;
  1260. function WinRegisterWithChild: Boolean;
  1261. var
  1262. WindowClass: WndClass;
  1263. begin
  1264. WindowClass.Style := graphwindowstyle;
  1265. WindowClass.lpfnWndProc := WndProc(@WindowProcParent);
  1266. WindowClass.cbClsExtra := 0;
  1267. WindowClass.cbWndExtra := 0;
  1268. WindowClass.hInstance := system.MainInstance;
  1269. if icon<>0 then
  1270. WindowClass.hIcon := icon
  1271. else
  1272. WindowClass.hIcon := LoadIcon(0, idi_Application);
  1273. WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  1274. WindowClass.hbrBackground := GetStockObject(BLACK_BRUSH);
  1275. if menu<>0 then
  1276. WindowClass.lpszMenuName := MAKEINTRESOURCE(menu)
  1277. else
  1278. WindowClass.lpszMenuName := nil;
  1279. WindowClass.lpszClassName := 'FPCGraphWindowMain';
  1280. WinRegisterWithChild:=RegisterClass(WindowClass) <> 0;
  1281. {$ifdef DEBUGCHILDS}
  1282. writeln('Main window successfully registered: WinRegisterWithChild is ',WinRegisterWithChild);
  1283. {$endif DEBUGCHILDS}
  1284. if WinRegisterWithChild then
  1285. begin
  1286. WindowClass.Style := CS_HREDRAW or CS_VREDRAW;
  1287. WindowClass.lpfnWndProc := WndProc(@WindowProcGraph);
  1288. WindowClass.cbClsExtra := 0;
  1289. WindowClass.cbWndExtra := 0;
  1290. WindowClass.hInstance := system.MainInstance;
  1291. WindowClass.hIcon := 0;
  1292. WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  1293. WindowClass.hbrBackground := GetStockObject(BLACK_BRUSH);
  1294. WindowClass.lpszMenuName := nil;
  1295. WindowClass.lpszClassName := 'FPCGraphWindowChild';
  1296. WinRegisterWithChild:=RegisterClass(WindowClass)<>0;
  1297. {$ifdef DEBUGCHILDS}
  1298. writeln('Child window registered: WinRegisterWithChild is ',WinRegisterWithChild);
  1299. {$endif DEBUGCHILDS}
  1300. end;
  1301. end;
  1302. var
  1303. // here we can force the creation of a maximized window }
  1304. extrastyle : cardinal;
  1305. { Create the Window Class }
  1306. function WinCreate : HWnd;
  1307. var
  1308. hWindow: HWnd;
  1309. begin
  1310. WinCreate:=0;
  1311. if UseChildWindow then
  1312. begin
  1313. ParentWindow:=CreateWindow('FPCGraphWindowMain', windowtitle,
  1314. WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN or extrastyle, longint(CW_USEDEFAULT), 0,
  1315. maxx+ChildOffset.Left+ChildOffset.Right+1+
  1316. 2*GetSystemMetrics(SM_CXFRAME),
  1317. maxy+ChildOffset.Top+ChildOffset.Bottom+1+
  1318. 2*GetSystemMetrics(SM_CYFRAME)+
  1319. GetSystemMetrics(SM_CYCAPTION),
  1320. 0, 0, system.MainInstance, nil);
  1321. if ParentWindow<>0 then
  1322. begin
  1323. ShowWindow(ParentWindow, SW_SHOW);
  1324. UpdateWindow(ParentWindow);
  1325. end
  1326. else
  1327. exit;
  1328. hWindow:=CreateWindow('FPCGraphWindowChild',nil,
  1329. WS_CHILD, ChildOffset.Left,ChildOffset.Top,
  1330. maxx+1,maxy+1,
  1331. ParentWindow, 0, system.MainInstance, nil);
  1332. if hwindow<>0 then
  1333. begin
  1334. ShowWindow(hwindow, SW_SHOW);
  1335. UpdateWindow(hwindow);
  1336. end
  1337. else
  1338. exit;
  1339. WinCreate:=hWindow;
  1340. end
  1341. else
  1342. begin
  1343. hWindow:=CreateWindow('FPCGraphWindow', windowtitle,
  1344. ws_OverlappedWindow or extrastyle, longint(CW_USEDEFAULT), 0,
  1345. maxx+1+2*GetSystemMetrics(SM_CXFRAME),
  1346. maxy+1+2*GetSystemMetrics(SM_CYFRAME)+
  1347. GetSystemMetrics(SM_CYCAPTION),
  1348. 0, 0, system.MainInstance, nil);
  1349. if hWindow <> 0 then
  1350. begin
  1351. ShowWindow(hWindow, SW_SHOW);
  1352. UpdateWindow(hWindow);
  1353. WinCreate:=hWindow;
  1354. end;
  1355. end;
  1356. end;
  1357. const
  1358. winregistered : boolean = false;
  1359. function MessageHandleThread(p : pointer) : DWord;StdCall;
  1360. var
  1361. AMessage: Msg;
  1362. begin
  1363. if not(winregistered) then
  1364. begin
  1365. if UseChildWindow then
  1366. begin
  1367. if not(WinRegisterWithChild) then
  1368. begin
  1369. MessageBox(0, 'Window registration failed', nil, mb_Ok);
  1370. ExitThread(1);
  1371. end;
  1372. end
  1373. else
  1374. begin
  1375. if not(WinRegister) then
  1376. begin
  1377. MessageBox(0, 'Window registration failed', nil, mb_Ok);
  1378. ExitThread(1);
  1379. end;
  1380. end;
  1381. winregistered:=true;
  1382. end;
  1383. GraphWindow:=WinCreate;
  1384. if longint(GraphWindow) = 0 then begin
  1385. MessageBox(0, 'Window creation failed', nil, mb_Ok);
  1386. ExitThread(1);
  1387. end;
  1388. while longint(GetMessage(@AMessage, 0, 0, 0))=longint(true) do
  1389. begin
  1390. TranslateMessage(AMessage);
  1391. DispatchMessage(AMessage);
  1392. end;
  1393. MessageHandleThread:=0;
  1394. end;
  1395. procedure InitWin32GUI16colors;
  1396. var
  1397. threadexitcode : longint;
  1398. begin
  1399. getmem(pal,sizeof(RGBrec)*maxcolor);
  1400. move(DefaultColors,pal^,sizeof(RGBrec)*maxcolor);
  1401. if (IntCurrentMode=mMaximizedWindow16) or
  1402. (IntCurrentMode=mMaximizedWindow256) or
  1403. (IntCurrentMode=mMaximizedWindow32k) or
  1404. (IntCurrentMode=mMaximizedWindow64k) or
  1405. (IntCurrentMode=mMaximizedWindow16M) then
  1406. extrastyle:=ws_maximize
  1407. else
  1408. extrastyle:=0;
  1409. { start graph subsystem }
  1410. InitializeCriticalSection(graphdrawing);
  1411. graphrunning:=false;
  1412. MessageThreadHandle:=CreateThread(nil,0,@MessageHandleThread,
  1413. nil,0,MessageThreadID);
  1414. repeat
  1415. GetExitCodeThread(MessageThreadHandle,@threadexitcode);
  1416. until graphrunning or (threadexitcode<>STILL_ACTIVE);
  1417. if threadexitcode<>STILL_ACTIVE then
  1418. _graphresult := grerror;
  1419. end;
  1420. procedure CloseGraph;
  1421. begin
  1422. If not isgraphmode then
  1423. begin
  1424. _graphresult := grnoinitgraph;
  1425. exit
  1426. end;
  1427. if UseChildWindow then
  1428. begin
  1429. { if the child window isn't destroyed }
  1430. { the main window can't be closed }
  1431. { I don't know any other way (FK) }
  1432. PostMessage(GraphWindow,wm_destroy,0,0);
  1433. PostMessage(ParentWindow,wm_destroy,0,0)
  1434. end
  1435. else
  1436. PostMessage(GraphWindow,wm_destroy,0,0);
  1437. PostThreadMessage(MessageThreadHandle,wm_quit,0,0);
  1438. WaitForSingleObject(MessageThreadHandle,Infinite);
  1439. CloseHandle(MessageThreadHandle);
  1440. DeleteCriticalSection(graphdrawing);
  1441. freemem(pal,sizeof(RGBrec)*maxcolor);
  1442. MessageThreadID := 0;
  1443. MessageThreadHandle := 0;
  1444. isgraphmode := false;
  1445. end;
  1446. procedure LineWin32GUI(X1, Y1, X2, Y2: smallint); {$ifndef fpc}far;{$endif fpc}
  1447. var X, Y : smallint;
  1448. deltax, deltay : smallint;
  1449. d, dinc1, dinc2: smallint;
  1450. xinc1 : smallint;
  1451. xinc2 : smallint;
  1452. yinc1 : smallint;
  1453. yinc2 : smallint;
  1454. i : smallint;
  1455. Flag : Boolean; { determines pixel direction in thick lines }
  1456. NumPixels : smallint;
  1457. PixelCount : smallint;
  1458. OldCurrentColor: Word;
  1459. swtmp : smallint;
  1460. TmpNumPixels : smallint;
  1461. col : longint;
  1462. pen,oldpen : hpen;
  1463. begin
  1464. if graphrunning then
  1465. begin
  1466. {******************************************}
  1467. { SOLID LINES }
  1468. {******************************************}
  1469. if lineinfo.LineStyle = SolidLn then
  1470. Begin
  1471. { Convert to global coordinates. }
  1472. x1 := x1 + StartXViewPort;
  1473. x2 := x2 + StartXViewPort;
  1474. y1 := y1 + StartYViewPort;
  1475. y2 := y2 + StartYViewPort;
  1476. { if fully clipped then exit... }
  1477. if ClipPixels then
  1478. begin
  1479. if LineClipped(x1,y1,x2,y2,StartXViewPort, StartYViewPort,
  1480. StartXViewPort+ViewWidth, StartYViewPort+ViewHeight) then
  1481. exit;
  1482. If LineInfo.Thickness=NormWidth then
  1483. Begin
  1484. EnterCriticalSection(graphdrawing);
  1485. {
  1486. if currentwritemode<>normalput then
  1487. begin
  1488. case currentwritemode of
  1489. XORPut:
  1490. begin
  1491. SetROP2(windc,R2_XORPEN);
  1492. SetROP2(bitmapdc,R2_XORPEN);
  1493. end;
  1494. AndPut:
  1495. begin
  1496. SetROP2(windc,R2_MASKPEN);
  1497. SetROP2(bitmapdc,R2_MASKPEN);
  1498. end;
  1499. OrPut:
  1500. begin
  1501. SetROP2(windc,R2_MERGEPEN);
  1502. SetROP2(bitmapdc,R2_MERGEPEN);
  1503. end;
  1504. end;
  1505. end;
  1506. }
  1507. col:=RGB(pal[CurrentColor].red,pal[CurrentColor].green,pal[CurrentColor].blue);
  1508. pen:=CreatePen(PS_SOLID,1,col);
  1509. if pen=0 then
  1510. writeln('Pen konnte nicht erzeugt werden!');
  1511. oldpen:=SelectObject(windc,pen);
  1512. MoveToEx(windc,x1,y1,nil);
  1513. Windows.LineTo(windc,x2,y2);
  1514. SetPixel(windc,x2,y2,col);
  1515. SelectObject(windc,oldpen);
  1516. oldpen:=SelectObject(bitmapdc,pen);
  1517. MoveToEx(bitmapdc,x1,y1,nil);
  1518. Windows.LineTo(bitmapdc,x2,y2);
  1519. SetPixel(bitmapdc,x2,y2,col);
  1520. SelectObject(bitmapdc,oldpen);
  1521. DeleteObject(pen);
  1522. {
  1523. if currentwritemode<>normalput then
  1524. begin
  1525. SetROP2(windc,R2_COPYPEN);
  1526. SetROP2(bitmapdc,R2_COPYPEN);
  1527. end;
  1528. }
  1529. LeaveCriticalSection(graphdrawing);
  1530. end
  1531. else
  1532. { Thick width lines }
  1533. begin
  1534. { Draw the pixels }
  1535. for i := 1 to numpixels do
  1536. begin
  1537. { all depending on the slope, we can determine }
  1538. { in what direction the extra width pixels will be put }
  1539. If Flag then
  1540. Begin
  1541. DirectPutPixelClip(x-1,y);
  1542. DirectPutPixelClip(x,y);
  1543. DirectPutPixelClip(x+1,y);
  1544. end
  1545. else
  1546. Begin
  1547. DirectPutPixelClip(x, y-1);
  1548. DirectPutPixelClip(x, y);
  1549. DirectPutPixelClip(x, y+1);
  1550. end;
  1551. if d < 0 then
  1552. begin
  1553. d := d + dinc1;
  1554. x := x + xinc1;
  1555. y := y + yinc1;
  1556. end
  1557. else
  1558. begin
  1559. d := d + dinc2;
  1560. x := x + xinc2;
  1561. y := y + yinc2;
  1562. end;
  1563. end;
  1564. end;
  1565. end;
  1566. end
  1567. else
  1568. {******************************************}
  1569. { begin patterned lines }
  1570. {******************************************}
  1571. Begin
  1572. { Convert to global coordinates. }
  1573. x1 := x1 + StartXViewPort;
  1574. x2 := x2 + StartXViewPort;
  1575. y1 := y1 + StartYViewPort;
  1576. y2 := y2 + StartYViewPort;
  1577. { if fully clipped then exit... }
  1578. if ClipPixels then
  1579. begin
  1580. if LineClipped(x1,y1,x2,y2,StartXViewPort, StartYViewPort,
  1581. StartXViewPort+ViewWidth, StartYViewPort+ViewHeight) then
  1582. exit;
  1583. end;
  1584. OldCurrentColor := CurrentColor;
  1585. PixelCount:=0;
  1586. if y1 = y2 then
  1587. Begin
  1588. { Check if we must swap }
  1589. if x1 >= x2 then
  1590. Begin
  1591. swtmp := x1;
  1592. x1 := x2;
  1593. x2 := swtmp;
  1594. end;
  1595. if LineInfo.Thickness = NormWidth then
  1596. Begin
  1597. for PixelCount:=x1 to x2 do
  1598. { optimization: PixelCount mod 16 }
  1599. if LinePatterns[PixelCount and 15] = TRUE then
  1600. begin
  1601. DirectPutPixel(PixelCount,y2);
  1602. end;
  1603. end
  1604. else
  1605. Begin
  1606. for i:=-1 to 1 do
  1607. Begin
  1608. for PixelCount:=x1 to x2 do
  1609. { Optimization from Thomas - mod 16 = and 15 }
  1610. {this optimization has been performed by the compiler
  1611. for while as well (JM)}
  1612. if LinePatterns[PixelCount and 15] = TRUE then
  1613. begin
  1614. DirectPutPixelClip(PixelCount,y2+i);
  1615. end;
  1616. end;
  1617. end;
  1618. end
  1619. else
  1620. if x1 = x2 then
  1621. Begin
  1622. { Check if we must swap }
  1623. if y1 >= y2 then
  1624. Begin
  1625. swtmp := y1;
  1626. y1 := y2;
  1627. y2 := swtmp;
  1628. end;
  1629. if LineInfo.Thickness = NormWidth then
  1630. Begin
  1631. for PixelCount:=y1 to y2 do
  1632. { compare if we should plot a pixel here , compare }
  1633. { with predefined line patterns... }
  1634. if LinePatterns[PixelCount and 15] = TRUE then
  1635. begin
  1636. DirectPutPixel(x1,PixelCount);
  1637. end;
  1638. end
  1639. else
  1640. Begin
  1641. for i:=-1 to 1 do
  1642. Begin
  1643. for PixelCount:=y1 to y2 do
  1644. { compare if we should plot a pixel here , compare }
  1645. { with predefined line patterns... }
  1646. if LinePatterns[PixelCount and 15] = TRUE then
  1647. begin
  1648. DirectPutPixelClip(x1+i,PixelCount);
  1649. end;
  1650. end;
  1651. end;
  1652. end
  1653. else
  1654. Begin
  1655. oldCurrentColor := CurrentColor;
  1656. { Calculate deltax and deltay for initialisation }
  1657. deltax := abs(x2 - x1);
  1658. deltay := abs(y2 - y1);
  1659. { Initialize all vars based on which is the independent variable }
  1660. if deltax >= deltay then
  1661. begin
  1662. Flag := FALSE;
  1663. { x is independent variable }
  1664. numpixels := deltax + 1;
  1665. d := (2 * deltay) - deltax;
  1666. dinc1 := deltay Shl 1;
  1667. dinc2 := (deltay - deltax) shl 1;
  1668. xinc1 := 1;
  1669. xinc2 := 1;
  1670. yinc1 := 0;
  1671. yinc2 := 1;
  1672. end
  1673. else
  1674. begin
  1675. Flag := TRUE;
  1676. { y is independent variable }
  1677. numpixels := deltay + 1;
  1678. d := (2 * deltax) - deltay;
  1679. dinc1 := deltax Shl 1;
  1680. dinc2 := (deltax - deltay) shl 1;
  1681. xinc1 := 0;
  1682. xinc2 := 1;
  1683. yinc1 := 1;
  1684. yinc2 := 1;
  1685. end;
  1686. { Make sure x and y move in the right directions }
  1687. if x1 > x2 then
  1688. begin
  1689. xinc1 := - xinc1;
  1690. xinc2 := - xinc2;
  1691. end;
  1692. if y1 > y2 then
  1693. begin
  1694. yinc1 := - yinc1;
  1695. yinc2 := - yinc2;
  1696. end;
  1697. { Start drawing at <x1, y1> }
  1698. x := x1;
  1699. y := y1;
  1700. If LineInfo.Thickness=ThickWidth then
  1701. Begin
  1702. TmpNumPixels := NumPixels-1;
  1703. { Draw the pixels }
  1704. for i := 0 to TmpNumPixels do
  1705. begin
  1706. { all depending on the slope, we can determine }
  1707. { in what direction the extra width pixels will be put }
  1708. If Flag then
  1709. Begin
  1710. { compare if we should plot a pixel here , compare }
  1711. { with predefined line patterns... }
  1712. if LinePatterns[i and 15] = TRUE then
  1713. begin
  1714. DirectPutPixelClip(x-1,y);
  1715. DirectPutPixelClip(x,y);
  1716. DirectPutPixelClip(x+1,y);
  1717. end;
  1718. end
  1719. else
  1720. Begin
  1721. { compare if we should plot a pixel here , compare }
  1722. { with predefined line patterns... }
  1723. if LinePatterns[i and 15] = TRUE then
  1724. begin
  1725. DirectPutPixelClip(x,y-1);
  1726. DirectPutPixelClip(x,y);
  1727. DirectPutPixelClip(x,y+1);
  1728. end;
  1729. end;
  1730. if d < 0 then
  1731. begin
  1732. d := d + dinc1;
  1733. x := x + xinc1;
  1734. y := y + yinc1;
  1735. end
  1736. else
  1737. begin
  1738. d := d + dinc2;
  1739. x := x + xinc2;
  1740. y := y + yinc2;
  1741. end;
  1742. end;
  1743. end
  1744. else
  1745. Begin
  1746. { instead of putting in loop , substract by one now }
  1747. TmpNumPixels := NumPixels-1;
  1748. { NormWidth }
  1749. for i := 0 to TmpNumPixels do
  1750. begin
  1751. if LinePatterns[i and 15] = TRUE then
  1752. begin
  1753. DirectPutPixel(x,y);
  1754. end;
  1755. if d < 0 then
  1756. begin
  1757. d := d + dinc1;
  1758. x := x + xinc1;
  1759. y := y + yinc1;
  1760. end
  1761. else
  1762. begin
  1763. d := d + dinc2;
  1764. x := x + xinc2;
  1765. y := y + yinc2;
  1766. end;
  1767. end;
  1768. end
  1769. end;
  1770. {******************************************}
  1771. { end patterned lines }
  1772. {******************************************}
  1773. { restore color }
  1774. CurrentColor:=OldCurrentColor;
  1775. end;
  1776. end;
  1777. end; { Line }
  1778. { multipage support could be done by using more than one background bitmap }
  1779. procedure SetVisualWin32GUI(page: word);
  1780. begin
  1781. end;
  1782. procedure SetActiveWin32GUI(page: word);
  1783. begin
  1784. end;
  1785. function queryadapterinfo : pmodeinfo;
  1786. var
  1787. mode: TModeInfo;
  1788. ScreenWidth,ScreenHeight : longint;
  1789. ScreenWidthMaximized,ScreenHeightMaximized : longint;
  1790. procedure SetupWin32GUIDefault;
  1791. begin
  1792. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1793. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1794. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1795. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1796. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1797. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1798. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1799. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1800. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1801. mode.OuttextXY:={$ifdef fpc}@{$endif}OuttextXYWin32GUI;
  1802. mode.VLine := {$ifdef fpc}@{$endif}VLine16Win32GUI;
  1803. // mode.circle := {$ifdef fpc}@{$endif}Circle16Win32GUI;
  1804. // doesn't work yet
  1805. // mode.Line:={$ifdef fpc}@{$endif}LineWin32GUI;
  1806. end;
  1807. begin
  1808. SaveVideoState:={$ifdef fpc}@{$endif}savestate;
  1809. RestoreVideoState:={$ifdef fpc}@{$endif}restorestate;
  1810. { we must take care of the border and caption }
  1811. ScreenWidth:=GetSystemMetrics(SM_CXSCREEN)-
  1812. 2*GetSystemMetrics(SM_CXFRAME);
  1813. ScreenHeight:=GetSystemMetrics(SM_CYSCREEN)-
  1814. 2*GetSystemMetrics(SM_CYFRAME)-
  1815. GetSystemMetrics(SM_CYCAPTION);
  1816. { for maximozed windows it's again different }
  1817. { here we've only a caption }
  1818. ScreenWidthMaximized:=GetSystemMetrics(SM_CXFULLSCREEN);
  1819. { neither GetSystemMetrics(SM_CYFULLSCREEN nor }
  1820. { SystemParametersInfo(SPI_GETWORKAREA) }
  1821. { takes a hidden try into account :( FK }
  1822. ScreenHeightMaximized:=GetSystemMetrics(SM_CYFULLSCREEN);
  1823. QueryAdapterInfo := ModeList;
  1824. { If the mode listing already exists... }
  1825. { simply return it, without changing }
  1826. { anything... }
  1827. if assigned(ModeList) then
  1828. exit;
  1829. { the first one becomes the standard mode }
  1830. if (ScreenWidth>=640) and (ScreenHeight>=480) then
  1831. begin
  1832. InitMode(mode);
  1833. mode.DriverNumber:= VGA;
  1834. mode.HardwarePages:= 0;
  1835. mode.ModeNumber:=VGAHi;
  1836. mode.ModeName:='640 x 480 x 16 Win32GUI';
  1837. mode.MaxColor := 16;
  1838. mode.PaletteSize := mode.MaxColor;
  1839. mode.DirectColor := FALSE;
  1840. mode.MaxX := 639;
  1841. mode.MaxY := 479;
  1842. SetupWin32GUIDefault;
  1843. mode.XAspect := 10000;
  1844. mode.YAspect := 10000;
  1845. AddMode(mode);
  1846. end;
  1847. if (ScreenWidth>=640) and (ScreenHeight>=200) then
  1848. begin
  1849. InitMode(mode);
  1850. { now add all standard VGA modes... }
  1851. mode.DriverNumber:= VGA;
  1852. mode.HardwarePages:= 0;
  1853. mode.ModeNumber:=VGALo;
  1854. mode.ModeName:='640 x 200 x 16 Win32GUI';
  1855. mode.MaxColor := 16;
  1856. mode.PaletteSize := mode.MaxColor;
  1857. mode.DirectColor := FALSE;
  1858. mode.MaxX := 639;
  1859. mode.MaxY := 199;
  1860. SetupWin32GUIDefault;
  1861. mode.XAspect := 10000;
  1862. mode.YAspect := 10000;
  1863. AddMode(mode);
  1864. end;
  1865. if (ScreenWidth>=640) and (ScreenHeight>=350) then
  1866. begin
  1867. InitMode(mode);
  1868. mode.DriverNumber:= VGA;
  1869. mode.HardwarePages:= 0;
  1870. mode.ModeNumber:=VGAMed;
  1871. mode.ModeName:='640 x 350 x 16 Win32GUI';
  1872. mode.MaxColor := 16;
  1873. mode.PaletteSize := mode.MaxColor;
  1874. mode.DirectColor := FALSE;
  1875. mode.MaxX := 639;
  1876. mode.MaxY := 349;
  1877. SetupWin32GUIDefault;
  1878. mode.XAspect := 10000;
  1879. mode.YAspect := 10000;
  1880. AddMode(mode);
  1881. end;
  1882. if (ScreenWidth>=640) and (ScreenHeight>=400) then
  1883. begin
  1884. InitMode(mode);
  1885. mode.DriverNumber:= VESA;
  1886. mode.HardwarePages:= 0;
  1887. mode.ModeNumber:=m640x400x256;
  1888. mode.ModeName:='640 x 400 x 256 Win32GUI';
  1889. mode.MaxColor := 256;
  1890. mode.PaletteSize := mode.MaxColor;
  1891. mode.DirectColor := FALSE;
  1892. mode.MaxX := 639;
  1893. mode.MaxY := 399;
  1894. SetupWin32GUIDefault;
  1895. mode.XAspect := 10000;
  1896. mode.YAspect := 10000;
  1897. AddMode(mode);
  1898. end;
  1899. if (ScreenWidth>=640) and (ScreenHeight>=480) then
  1900. begin
  1901. InitMode(mode);
  1902. mode.DriverNumber:= VESA;
  1903. mode.HardwarePages:= 0;
  1904. mode.ModeNumber:=m640x480x256;
  1905. mode.ModeName:='640 x 480 x 256 Win32GUI';
  1906. mode.MaxColor := 256;
  1907. mode.PaletteSize := mode.MaxColor;
  1908. mode.DirectColor := FALSE;
  1909. mode.MaxX := 639;
  1910. mode.MaxY := 479;
  1911. SetupWin32GUIDefault;
  1912. mode.XAspect := 10000;
  1913. mode.YAspect := 10000;
  1914. AddMode(mode);
  1915. end;
  1916. { add 800x600 only if screen is large enough }
  1917. If (ScreenWidth>=800) and (ScreenHeight>=600) then
  1918. begin
  1919. InitMode(mode);
  1920. mode.DriverNumber:= VESA;
  1921. mode.HardwarePages:= 0;
  1922. mode.ModeNumber:=m800x600x16;
  1923. mode.ModeName:='800 x 600 x 16 Win32GUI';
  1924. mode.MaxColor := 16;
  1925. mode.PaletteSize := mode.MaxColor;
  1926. mode.DirectColor := FALSE;
  1927. mode.MaxX := 799;
  1928. mode.MaxY := 599;
  1929. SetupWin32GUIDefault;
  1930. mode.XAspect := 10000;
  1931. mode.YAspect := 10000;
  1932. AddMode(mode);
  1933. InitMode(mode);
  1934. mode.DriverNumber:= VESA;
  1935. mode.HardwarePages:= 0;
  1936. mode.ModeNumber:=m800x600x256;
  1937. mode.ModeName:='800 x 600 x 256 Win32GUI';
  1938. mode.MaxColor := 256;
  1939. mode.PaletteSize := mode.MaxColor;
  1940. mode.DirectColor := FALSE;
  1941. mode.MaxX := 799;
  1942. mode.MaxY := 599;
  1943. SetupWin32GUIDefault;
  1944. mode.XAspect := 10000;
  1945. mode.YAspect := 10000;
  1946. AddMode(mode);
  1947. end;
  1948. { add 1024x768 only if screen is large enough }
  1949. If (ScreenWidth>=1024) and (ScreenHeight>=768) then
  1950. begin
  1951. InitMode(mode);
  1952. mode.DriverNumber:= VESA;
  1953. mode.HardwarePages:= 0;
  1954. mode.ModeNumber:=m1024x768x16;
  1955. mode.ModeName:='1024 x 768 x 16 Win32GUI';
  1956. mode.MaxColor := 16;
  1957. mode.PaletteSize := mode.MaxColor;
  1958. mode.DirectColor := FALSE;
  1959. mode.MaxX := 1023;
  1960. mode.MaxY := 767;
  1961. SetupWin32GUIDefault;
  1962. mode.XAspect := 10000;
  1963. mode.YAspect := 10000;
  1964. AddMode(mode);
  1965. InitMode(mode);
  1966. mode.DriverNumber:= VESA;
  1967. mode.HardwarePages:= 0;
  1968. mode.ModeNumber:=m1024x768x256;
  1969. mode.ModeName:='1024 x 768 x 256 Win32GUI';
  1970. mode.MaxColor := 256;
  1971. mode.PaletteSize := mode.MaxColor;
  1972. mode.DirectColor := FALSE;
  1973. mode.MaxX := 1023;
  1974. mode.MaxY := 768;
  1975. SetupWin32GUIDefault;
  1976. mode.XAspect := 10000;
  1977. mode.YAspect := 10000;
  1978. AddMode(mode);
  1979. end;
  1980. { add 1280x1024 only if screen is large enough }
  1981. If (ScreenWidth>=1280) and (ScreenHeight>=1024) then
  1982. begin
  1983. InitMode(mode);
  1984. mode.DriverNumber:= VESA;
  1985. mode.HardwarePages:= 0;
  1986. mode.ModeNumber:=m1280x1024x16;
  1987. mode.ModeName:='1280 x 1024 x 16 Win32GUI';
  1988. mode.MaxColor := 16;
  1989. mode.PaletteSize := mode.MaxColor;
  1990. mode.DirectColor := FALSE;
  1991. mode.MaxX := 1279;
  1992. mode.MaxY := 1023;
  1993. SetupWin32GUIDefault;
  1994. mode.XAspect := 10000;
  1995. mode.YAspect := 10000;
  1996. AddMode(mode);
  1997. InitMode(mode);
  1998. mode.DriverNumber:= VESA;
  1999. mode.HardwarePages:= 0;
  2000. mode.ModeNumber:=m1280x1024x256;
  2001. mode.ModeName:='1280 x 1024 x 256 Win32GUI';
  2002. mode.MaxColor := 256;
  2003. mode.PaletteSize := mode.MaxColor;
  2004. mode.DirectColor := FALSE;
  2005. mode.MaxX := 1279;
  2006. mode.MaxY := 1023;
  2007. SetupWin32GUIDefault;
  2008. mode.XAspect := 10000;
  2009. mode.YAspect := 10000;
  2010. AddMode(mode);
  2011. end;
  2012. { at least we add a mode with the largest possible window }
  2013. InitMode(mode);
  2014. mode.DriverNumber:= VESA;
  2015. mode.HardwarePages:= 0;
  2016. mode.ModeNumber:=mLargestWindow16;
  2017. mode.ModeName:='Largest Window x 16';
  2018. mode.MaxColor := 16;
  2019. mode.PaletteSize := mode.MaxColor;
  2020. mode.DirectColor := FALSE;
  2021. mode.MaxX := ScreenWidth-1;
  2022. mode.MaxY := ScreenHeight-1;
  2023. SetupWin32GUIDefault;
  2024. mode.XAspect := 10000;
  2025. mode.YAspect := 10000;
  2026. AddMode(mode);
  2027. InitMode(mode);
  2028. mode.DriverNumber:= VESA;
  2029. mode.HardwarePages:= 0;
  2030. mode.ModeNumber:=mLargestWindow256;
  2031. mode.ModeName:='Largest Window x 256';
  2032. mode.MaxColor := 256;
  2033. mode.PaletteSize := mode.MaxColor;
  2034. mode.DirectColor := FALSE;
  2035. mode.MaxX := ScreenWidth-1;
  2036. mode.MaxY := ScreenHeight-1;
  2037. SetupWin32GUIDefault;
  2038. mode.XAspect := 10000;
  2039. mode.YAspect := 10000;
  2040. AddMode(mode);
  2041. { .. and a maximized window }
  2042. InitMode(mode);
  2043. mode.DriverNumber:= VESA;
  2044. mode.HardwarePages:= 0;
  2045. mode.ModeNumber:=mMaximizedWindow16;
  2046. mode.ModeName:='Maximized Window x 16';
  2047. mode.MaxColor := 16;
  2048. mode.PaletteSize := mode.MaxColor;
  2049. mode.DirectColor := FALSE;
  2050. mode.MaxX := ScreenWidthMaximized-1;
  2051. mode.MaxY := ScreenHeightMaximized-1;
  2052. SetupWin32GUIDefault;
  2053. mode.XAspect := 10000;
  2054. mode.YAspect := 10000;
  2055. AddMode(mode);
  2056. InitMode(mode);
  2057. mode.DriverNumber:= VESA;
  2058. mode.HardwarePages:= 0;
  2059. mode.ModeNumber:=mMaximizedWindow256;
  2060. mode.ModeName:='Maximized Window x 256';
  2061. mode.MaxColor := 256;
  2062. mode.PaletteSize := mode.MaxColor;
  2063. mode.DirectColor := FALSE;
  2064. mode.MaxX := ScreenWidthMaximized-1;
  2065. mode.MaxY := ScreenHeightMaximized-1;
  2066. SetupWin32GUIDefault;
  2067. mode.XAspect := 10000;
  2068. mode.YAspect := 10000;
  2069. AddMode(mode);
  2070. end;
  2071. begin
  2072. InitializeGraph;
  2073. charmessagehandler:=nil;
  2074. mousemessagehandler:=nil;
  2075. commandmessagehandler:=nil;
  2076. notifymessagehandler:=nil;
  2077. OnGraphWindowCreation:=nil;
  2078. end.