line.ppi 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team
  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. procedure DrawPattern(x1,x2,y:integer);
  12. begin
  13. asm
  14. movswl x1,%ebx
  15. movswl x2,%ecx
  16. movswl y,%edx
  17. subl %ebx,%ecx
  18. incl %ecx
  19. movl _X_ARRAY(,%ebx,4),%eax
  20. movl _Y_ARRAY(,%edx,4),%edi // { Offset in %edi }
  21. addl %eax,%edi
  22. andl _WINLOMASK,%edi
  23. andl $0x7,%edx // { y and $7 }
  24. shll $0x5,%edx // { y * 8 * sizeof(longint) }
  25. leal _PATTERNBUFFER,%esi //
  26. addl %edx,%esi // { Offset in Patternbuffer }
  27. movl $0x7,%edx
  28. addl _WBUFFER,%edi
  29. pushw %es
  30. movw _SEG_WRITE,%ax
  31. movw %ax,%es
  32. testw $1,_AKTWRITEMODE
  33. jnz pl_xord
  34. pl_movd:
  35. testw $1,_BYTESPERPIXEL
  36. jz pl_movdw
  37. .align 4,0x90
  38. pl_movdb:
  39. andl %edx,%ebx
  40. movb (%esi,%ebx,4),%al
  41. movb %al,%es:(%edi)
  42. incl %edi
  43. incl %ebx
  44. decl %ecx
  45. jnz pl_movdb
  46. jz pl_d_exit
  47. .align 4,0x90
  48. pl_movdw:
  49. andl %edx,%ebx
  50. movw (%esi,%ebx,4),%ax
  51. movw %ax,%es:(%edi)
  52. addl $2,%edi
  53. incl %ebx
  54. decl %ecx
  55. jnz pl_movdw
  56. jz pl_d_exit
  57. pl_xord:
  58. testw $1,_BYTESPERPIXEL
  59. jz pl_xordw
  60. .align 4,0x90
  61. pl_xordb:
  62. andl %edx,%ebx
  63. movb (%esi,%ebx,4),%al
  64. xorb %al,%es:(%edi)
  65. incl %edi
  66. incl %ebx
  67. decl %ecx
  68. jnz pl_xordb
  69. jz pl_d_exit
  70. .align 4,0x90
  71. pl_xordw:
  72. andl %edx,%ebx
  73. movw (%esi,%ebx,4),%ax
  74. xorw %ax,%es:(%edi)
  75. addl $2,%edi
  76. incl %ebx
  77. decl %ecx
  78. jnz pl_xordw
  79. pl_d_exit:
  80. popw %es
  81. pl_exit:
  82. end;
  83. end;
  84. procedure PatternLine(x1,x2,y:integer);
  85. var bank1,bank2 : longint;
  86. ofs1,ofs2 : longint;
  87. diff : integer;
  88. viewport : ViewPortType;
  89. begin
  90. x1:= x1 + aktviewport.x1 ;
  91. y:= y + aktviewport.y1 ;
  92. x2:= x2 + aktviewport.x1 ;
  93. if aktviewport.clip then viewport:=aktviewport else viewport:=aktscreen;
  94. if (y < viewport.y1) or (y > viewport.y2) then exit;
  95. if x1 > x2 then begin diff:=x2; x2:=x1; x1:=diff; end;
  96. if (x1> viewport.x2) or (x2< viewport.x1) then exit;
  97. if x1 < viewport.x1 then x1:=viewport.x1;
  98. if x2 > viewport.x2 then x2:=viewport.x2;
  99. ofs1:= Y_ARRAY[y];
  100. ofs2:= ofs1 + X_ARRAY[x2];
  101. ofs1:= ofs1 + X_ARRAY[x1];
  102. bank1:=ofs1 shr winshift;
  103. bank2:=ofs2 shr winshift;
  104. if bank1 <> AW_BANK then
  105. begin
  106. Switchbank(bank1);
  107. AW_BANK:=bank1;
  108. end;
  109. if bank1 <> bank2 then begin
  110. diff:=(((bank2 shl winshift)-ofs1) div BytesPerPixel)+x1;
  111. DrawPattern(x1,diff-1,y);
  112. Switchbank(bank2); AW_BANK:=bank2;
  113. DrawPattern(diff,x2,y);
  114. end else DrawPattern(x1,x2,y);
  115. end;
  116. procedure HorizontalLine(x1,x2,y:integer);
  117. { without bankswitching }
  118. begin
  119. asm
  120. movw %es,%dx
  121. movzwl y,%ebx
  122. movzwl x1,%eax
  123. movzwl x2,%ecx
  124. incl %ecx
  125. movl _X_ARRAY(,%eax,4),%eax
  126. movl _X_ARRAY(,%ecx,4),%ecx
  127. movl _Y_ARRAY(,%ebx,4),%edi // { Offset in %edi }
  128. subl %eax,%ecx // { Counter }
  129. addl %eax,%edi
  130. andl _WINLOMASK,%edi
  131. movl _AKTCOLOR,%eax
  132. movzwl _AKTWRITEMODE,%esi
  133. addl _WBUFFER,%edi
  134. movw _SEG_WRITE,%bx
  135. movw %bx,%es
  136. testl %esi,%esi // { Writemode ? }
  137. jnz hl_xor
  138. shrl %ecx
  139. jnc _movw
  140. stosb
  141. _movw:
  142. shrl %ecx
  143. jnc _movd
  144. stosw
  145. _movd:
  146. rep
  147. stosl
  148. jmp hl_exit
  149. hl_xor: // -------------------------------------------------
  150. movl $4,%esi
  151. shrl %ecx
  152. jnc hl_xorw
  153. xorb %al,%es:(%edi)
  154. incl %edi
  155. hl_xorw:
  156. shrl %ecx
  157. jnc hl_xord
  158. xorw %ax,%es:(%edi)
  159. addl $2,%edi
  160. hl_xord:
  161. jecxz hl_exit
  162. .align 4,0x90
  163. hl_xorloop:
  164. xorl %eax,%es:(%edi)
  165. addl %esi,%edi
  166. decl %ecx
  167. jnz hl_xorloop
  168. hl_exit:
  169. movw %dx,%es
  170. end;
  171. end;
  172. procedure Line(x1,y1,x2,y2: integer);
  173. var dx,dy,d : longint;
  174. i,j : integer;
  175. ofs,ofs2 : longint;
  176. i1,i2,ix : longint;
  177. x,y : Integer;
  178. flag,dontcheck : Boolean;
  179. viewport : ViewPortType;
  180. begin
  181. x1:= x1 + aktviewport.x1 ;
  182. y1:= y1 + aktviewport.y1 ;
  183. x2:= x2 + aktviewport.x1 ;
  184. y2:= y2 + aktviewport.y1 ;
  185. if aktviewport.clip then viewport:=aktviewport else viewport:=aktscreen;
  186. { ************ Horizontalline ************** }
  187. if y1=y2 then begin
  188. if x1>x2 then begin d:=x1; x1:=x2; x2:=d; end;
  189. if aktlineinfo.thickness=3 then y1:=y1-1;
  190. i:=0;
  191. if x1 < viewport.x1 then x1:=viewport.x1;
  192. if x2 > viewport.x2 then x2:=viewport.x2;
  193. if (y1 > viewport.y2) or (x1 > x2 ) then exit;
  194. repeat
  195. if (y1 >= viewport.y1) and (y1 <=viewport.y2)
  196. then begin
  197. ofs:= Y_ARRAY[y1];
  198. ofs2:=ofs+X_ARRAY[x2];
  199. ofs:= ofs+X_ARRAY[x1];
  200. i1:=ofs shr winshift; i2:=ofs2 shr winshift;
  201. if i1 <> aw_bank then
  202. begin
  203. switchbank(i1);
  204. aw_bank:=i1;
  205. end;
  206. if i1=i2 then Horizontalline(x1,x2,y1)
  207. else
  208. begin
  209. dx:=((i2 shl winshift)-ofs) div BytesPerPixel;
  210. horizontalline(x1,x1+dx-1,y1);
  211. Switchbank(i2); AW_BANK:=i2;
  212. horizontalline(dx+x1,x2,y1);
  213. end;
  214. end;
  215. i:=i+1; y1:=y1+1;
  216. until i=aktlineinfo.thickness;
  217. exit;
  218. end;
  219. { *********** End Horizontalline *********** }
  220. if y1 > y2 then begin
  221. x:=x1; x1:=x2; x2:=x;
  222. y:=y1; y1:=y2; y2:=y;
  223. end;
  224. { ************** Verticalline ************** }
  225. if x1=x2 then
  226. begin
  227. if y1 < viewport.y1 then y1:=viewport.y1;
  228. if y2 > viewport.y2 then y2:=viewport.y2;
  229. if ( y1 > y2) or (x1 < viewport.x1) or (x1 > viewport.x2) then exit;
  230. ofs:= Y_Array[y2]+X_Array[x1];
  231. ofs2:=Y_Array[y1]+X_Array[x1];
  232. while ofs >= ofs2 do begin
  233. pixel(ofs);
  234. if aktlineinfo.thickness=3 then begin
  235. if x1>viewport.x1 then pixel(ofs-1);
  236. if x1<viewport.x2 then pixel(ofs+1);
  237. end;
  238. ofs:=ofs-BytesPerLine;
  239. end;
  240. exit;
  241. end;
  242. { ************ End Verticalline ************ }
  243. dy:=y2-y1;
  244. dx:=abs(x2-x1);
  245. if x1>x2 then ix:=-1 else ix:= 1;
  246. if dx<dy then begin d:=dx; dx:=dy; dy:=d; Flag:=true end else Flag:=false;
  247. i1:=dy shl 1;
  248. d:=i1 - dx;
  249. i2:=(dx shl 1)-i1;
  250. dontcheck:=(y1>=viewport.y1) and (y2<=viewport.y2) and
  251. (x1>=viewport.x1) and (x1<=viewport.x2) and
  252. (x2>=viewport.x1) and (x2<=viewport.x2);
  253. if aktlineinfo.thickness=3 then
  254. { *************************************** }
  255. { **** Thickness=3 with rangechecking *** }
  256. { *************************************** }
  257. begin
  258. repeat
  259. for i:=y1-1 to y1+1 do
  260. for j:=x1-1 to x1+1 do
  261. if (i>=viewport.y1) and (j>=viewport.x1) and
  262. (j<=viewport.x2) and (i<=viewport.y2) then pixel(X_ARRAY[j]+Y_ARRAY[i]);
  263. if d < 0
  264. then begin
  265. if Flag then y1:=y1+1 else x1:=x1+ix;
  266. d:=d+i1;
  267. end
  268. else begin
  269. d:=d-i2; x1:=x1+ix; y1:=y1+1;
  270. end;
  271. dx:=dx-1;
  272. until ( dx=0 ) or ( y1 > viewport.y2 )
  273. end else
  274. if dontcheck then
  275. { *************************************** }
  276. { ** Thickness=1 without rangechecking ** }
  277. { *************************************** }
  278. begin
  279. asm
  280. pushw %gs
  281. movw _SEG_WRITE,%ax
  282. movw %ax,%gs // { ScreenSelector }
  283. // selfmodify to speedup Code
  284. xorl %ebx,%ebx
  285. movl ix,%eax
  286. testl %eax,%eax
  287. jns line1_inc
  288. movl $0x08,%ebx
  289. line1_inc:
  290. addl $0x43,%ebx // Opcode incl %ebx
  291. movb %bl,inc_dec1
  292. movb %bl,inc_dec2
  293. movl i1,%eax
  294. movl %eax,i1long1
  295. movl %eax,i1long2
  296. movl i2,%eax
  297. movl %eax,i2long
  298. movl _WBUFFER,%eax
  299. movl %eax,wbuffer
  300. movl _WINSHIFT,%eax
  301. movb %al,winshift
  302. movl _WINLOMASK,%eax
  303. movl %eax,winlomask
  304. movb $0x90,operandprefix // Opcade nop
  305. testw $1,_AKTWRITEMODE
  306. jnz line1XOR
  307. movb $0x88,linemode // Opcode movb
  308. jmp linedepth
  309. line1XOR:
  310. movb $0x30,linemode // Opcode xorb
  311. linedepth:
  312. testw $1,_BYTESPERPIXEL
  313. jnz is_byte
  314. movb $0x66,operandprefix // Prefix for operandsize
  315. incb linemode // incr. for wordacces
  316. is_byte:
  317. movl dx,%ecx
  318. movl _AKTCOLOR,%eax
  319. movzwl y1,%esi
  320. movzwl x1,%ebx
  321. movswl d,%edx
  322. //----------------//
  323. // Linemainloop //
  324. //----------------//
  325. .align 4,0x90
  326. line1_loop:
  327. pushl %ecx
  328. pushl %eax
  329. movl _Y_ARRAY(,%esi,4),%edi
  330. addl _X_ARRAY(,%ebx,4),%edi
  331. movl %edi,%eax
  332. .byte 0x81,0xe7 // andl ..,%edi
  333. winlomask: //
  334. .long 0x88888888 // _WINLOMASK
  335. .byte 0xc1,0xe8 // shrl ..,%eax
  336. winshift: //
  337. .byte 0x88 // _WINSHIFT
  338. pushl %edi
  339. cmpl _AW_BANK,%eax
  340. je line1_dontswitch
  341. pushl %ebx
  342. pushl %edx
  343. pushl %esi
  344. movl %eax,_AW_BANK // newbank
  345. pushl %eax
  346. movl _BANKSWITCHPTR,%eax
  347. call %eax
  348. popl %esi
  349. popl %edx
  350. popl %ebx
  351. .align 4,0x90
  352. line1_dontswitch:
  353. popl %edi
  354. popl %eax
  355. popl %ecx
  356. .byte 0x81,0xc7 // addl ..,%edi
  357. wbuffer: //
  358. .long 0x88888888 // _WBUFFER
  359. operandprefix:
  360. .byte 0x90 // Operandprefix (nop for Byte,$66 for Word)
  361. .byte 0x65 // Segmentprefix %gs:
  362. linemode:
  363. .byte 0x88,0x07 // modified OpCode<movb,xorb...>,%edi
  364. decl %ecx
  365. jz line1_end
  366. testl %edx,%edx // { if d < 0 then }
  367. jns is_positive
  368. testb $1,flag // { if flag then }
  369. jz no_flag
  370. incl %esi // { y1:=y1+1 }
  371. .byte 0x81,0xc2
  372. i1long1:
  373. .long 0x88888888 // { d:=d+i1 }
  374. jmp line1_loop
  375. .align 4,0x90
  376. no_flag:
  377. inc_dec1:
  378. .byte 0x88 // { x1:=x1+ix }
  379. .byte 0x81,0xc2
  380. i1long2:
  381. .long 0x88888888 // { d:=d+i1 }
  382. jmp line1_loop
  383. .align 4,0x90
  384. is_positive:
  385. inc_dec2:
  386. .byte 0x88 // { x1:=x1+ix }
  387. incl %esi // { y1:=y1+1 }
  388. .byte 0x81,0xea
  389. i2long:
  390. .long 0x88888888 // { d:=d-i2 }
  391. jmp line1_loop
  392. line1_end:
  393. popw %gs
  394. end;
  395. end else
  396. { *************************************** }
  397. { **** Thickness=1 with rangechecking *** }
  398. { *************************************** }
  399. begin
  400. repeat
  401. if y1 > viewport.y2 then exit;
  402. if (y1>=viewport.y1) and (x1>=viewport.x1) and
  403. (x1<=viewport.x2) then pixel(Y_ARRAY[y1]+X_ARRAY[x1]);
  404. if d < 0
  405. then begin
  406. if Flag then y1:=y1+1 else x1:=x1+ix;
  407. d:=d+i1;
  408. end
  409. else begin
  410. d:=d-i2; x1:=x1+ix; y1:=y1+1;
  411. end;
  412. dx:=dx-1;
  413. until dx=0 ;
  414. end;
  415. end;
  416. procedure MoveTo(x,y : integer);
  417. begin
  418. _graphresult:=grOk;
  419. if not isgraphmode then
  420. begin
  421. _graphresult:=grnoinitgraph;
  422. exit;
  423. end;
  424. curx:=x;
  425. cury:=y;
  426. end;
  427. procedure MoveRel(dx,dy : integer);
  428. begin
  429. _graphresult:=grOk;
  430. if not isgraphmode then
  431. begin
  432. _graphresult:=grnoinitgraph;
  433. exit;
  434. end;
  435. curx:=curx+dx;
  436. cury:=cury+dy;
  437. end;
  438. procedure LineTo(x,y : integer);
  439. begin
  440. _graphresult:=grOk;
  441. if not isgraphmode then
  442. begin
  443. _graphresult:=grnoinitgraph;
  444. exit;
  445. end;
  446. Line(curx,cury,x,y);
  447. MoveTo(x,y);
  448. end;
  449. procedure LineRel(dx,dy : integer);
  450. begin
  451. _graphresult:=grOk;
  452. if not isgraphmode then
  453. begin
  454. _graphresult:=grnoinitgraph;
  455. exit;
  456. end;
  457. Line(curx,cury,curx+dx,cury+dy);
  458. curx:=curx+dx;
  459. cury:=cury+dy;
  460. end;
  461. procedure SetLineStyle(LineStyle : word;pattern : word;thickness : word);
  462. const
  463. linepatterns : array[0..3] of word =
  464. ($ffff,$aaaa,$fafa,$ffff);
  465. begin
  466. if (linestyle<0) or (linestyle>4) or
  467. ((thickness<>1) and (thickness<>3)) then
  468. begin
  469. _graphresult:=grerror;
  470. exit;
  471. end;
  472. aktlineinfo.linestyle:=linestyle;
  473. if aktlineinfo.linestyle=UserBitLn then
  474. aktlineinfo.pattern:=pattern
  475. else
  476. aktlineinfo.pattern:=linepatterns[aktlineinfo.linestyle];
  477. aktlineinfo.thickness:=thickness;
  478. end;
  479. procedure DrawPoly(points : word;var polypoints);
  480. type
  481. ppointtype = ^pointtype;
  482. var
  483. i : longint;
  484. begin
  485. _graphresult:=grOk;
  486. if not isgraphmode then
  487. begin
  488. _graphresult:=grnoinitgraph;
  489. exit;
  490. end;
  491. line(ppointtype(@polypoints)[points-1].x,
  492. ppointtype(@polypoints)[points-1].y,
  493. ppointtype(@polypoints)[0].x,
  494. ppointtype(@polypoints)[0].y);
  495. for i:=0 to points-2 do
  496. line(ppointtype(@polypoints)[i].x,
  497. ppointtype(@polypoints)[i].y,
  498. ppointtype(@polypoints)[i+1].x,
  499. ppointtype(@polypoints)[i+1].y);
  500. end;
  501. {
  502. $Log$
  503. Revision 1.1 1998-03-25 11:18:42 root
  504. Initial revision
  505. Revision 1.4 1998/03/03 22:48:43 florian
  506. + graph.drawpoly procedure
  507. + putimage with xorput uses mmx if available
  508. Revision 1.3 1998/01/26 11:58:18 michael
  509. + Added log at the end
  510. Working file: rtl/dos/ppi/line.ppi
  511. description:
  512. ----------------------------
  513. revision 1.2
  514. date: 1997/12/01 12:21:31; author: michael; state: Exp; lines: +14 -0
  515. + added copyright reference in header.
  516. ----------------------------
  517. revision 1.1
  518. date: 1997/11/27 08:33:51; author: michael; state: Exp;
  519. Initial revision
  520. ----------------------------
  521. revision 1.1.1.1
  522. date: 1997/11/27 08:33:51; author: michael; state: Exp; lines: +0 -0
  523. FPC RTL CVS start
  524. =============================================================================
  525. }