text.inc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,98 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. {***************************************************************************}
  12. { Text output routines }
  13. {***************************************************************************}
  14. const
  15. maxfonts = 16; { maximum possible fonts }
  16. MaxChars = 255; { Maximum nr. of characters in a file }
  17. Prefix_Size = $80; { prefix size to skip }
  18. SIGNATURE = '+'; { Signature of CHR file }
  19. type
  20. pbyte = ^byte;
  21. pword = ^word;
  22. { Prefix header of Font file }
  23. PFHeader = ^TFHeader;
  24. TFHeader = packed record
  25. header_size: word; {* Version 2.0 Header Format *}
  26. font_name: array[1..4] of char;
  27. font_size: word; {* Size in byte of file *}
  28. font_major: byte; {* Driver Version Information *}
  29. font_minor: byte;
  30. min_major: byte; {* BGI Revision Information *}
  31. min_minor: byte;
  32. end;
  33. { Font record information }
  34. PHeader = ^THeader;
  35. THeader = packed record
  36. Signature: char; { signature byte }
  37. Nr_chars: integer; { number of characters in file }
  38. Reserved: byte;
  39. First_char: byte; { first character in file }
  40. cdefs : integer; { offset to character definitions }
  41. scan_flag: byte; { TRUE if char is scanable }
  42. org_to_cap: byte; { Height from origin to top of capitol }
  43. org_to_base:byte; { Height from origin to baseline }
  44. org_to_dec: byte; { Height from origin to bot of decender }
  45. _reserved: array[1..4] of char;
  46. Unused: byte;
  47. end;
  48. TOffsetTable =array[0..MaxChars] of Integer;
  49. TWidthTable =array[0..MaxChars] of byte;
  50. tfontrec = packed record
  51. name : string[8];
  52. header : THeader; { font header }
  53. pheader : TFHeader; { prefix header }
  54. offsets : TOffsetTable;
  55. widths : TWidthTable;
  56. instr : pchar;
  57. end;
  58. pStroke = ^TStroke;
  59. TStroke = packed record
  60. opcode: byte;
  61. x: integer; { relative x offset character }
  62. y: integer; { relative y offset character }
  63. end;
  64. TStrokes = Array[0..1000] of TStroke;
  65. opcodes = (_END_OF_CHAR, _DO_SCAN, _MOVE, _DRAW);
  66. var
  67. fonts : array[1..maxfonts] of tfontrec;
  68. Strokes: TStrokes; {* Stroke Data Base *}
  69. Stroke_count: Array[0..MaxChars] of integer; {* Stroke Count Table *}
  70. {***************************************************************************}
  71. { Internal support routines }
  72. {***************************************************************************}
  73. function testfont(p : pchar) : boolean;
  74. begin
  75. testfont:=(p[0]='P') and
  76. (p[1]='K') and
  77. (p[2]=#8) and
  78. (p[3]=#8);
  79. end;
  80. function InstallUserFont(const FontFileName : string) : integer;
  81. begin
  82. _graphresult:=grOk;
  83. { first check if we do not allocate too many fonts! }
  84. if installedfonts=maxfonts then
  85. begin
  86. _graphresult:=grError;
  87. InstallUserFont := DefaultFont;
  88. exit;
  89. end;
  90. inc(installedfonts);
  91. fonts[installedfonts].name:=FontFileName;
  92. fonts[installedfonts].instr := nil;
  93. InstallUserFont:=installedfonts;
  94. end;
  95. function Decode(byte1,byte2: char; var x,y: integer): integer;
  96. { This routines decoes a signle word in a font opcode section }
  97. { to a stroke record. }
  98. var
  99. b1,b2: shortint;
  100. Begin
  101. b1:=shortint(byte1);
  102. b2:=shortint(byte2);
  103. { Decode the CHR OPCODE }
  104. Decode:=integer(((b1 and $80) shr 6)+((b2 and $80) shr 7));
  105. { Now get the X,Y coordinates }
  106. { bit 0..7 only which are considered }
  107. { signed values. }
  108. {$R-}
  109. b1:=b1 and $7f;
  110. b2:=b2 and $7f;
  111. { Now if the MSB of these values are set }
  112. { then the value is signed, therefore we }
  113. { sign extend it... }
  114. if (b1 and $40)<>0 then b1:=b1 or $80;
  115. if (b2 and $40)<>0 then b2:=b2 or $80;
  116. x:=integer(b1);
  117. y:=integer(b2);
  118. {$ifdef debug}
  119. {$R+}
  120. {$endif debug}
  121. end;
  122. function unpack(buf: pchar; index: integer; var Stroke: TStrokes): integer;
  123. var
  124. pb: pword;
  125. po: TStrokes;
  126. num_ops: integer;
  127. opcode, i, opc: word;
  128. counter: integer;
  129. lindex: integer;
  130. jx, jy: integer;
  131. begin
  132. num_ops := 0;
  133. counter := index;
  134. lindex :=0;
  135. while TRUE do {* For each byte in buffer *}
  136. Begin
  137. Inc(num_ops); {* Count the operation *}
  138. opcode := decode( buf[counter], buf[counter+1] ,jx, jy );
  139. Inc(counter,2);
  140. if( opcode = ord(_END_OF_CHAR) ) then break; {* Exit loop at end of char *}
  141. end;
  142. counter:=index;
  143. for i:=0 to num_ops-1 do { /* For each opcode in buffer */ }
  144. Begin
  145. opc := decode(buf[counter], buf[counter+1], po[lindex].x, po[lindex].y); {* Decode the data field *}
  146. inc(counter,2);
  147. po[lindex].opcode := opc; {* Save the opcode *}
  148. Inc(lindex);
  149. end;
  150. Stroke:=po;
  151. unpack := num_ops; {* return OPS count *}
  152. end;
  153. procedure GetTextPosition(var xpos,ypos: longint; const TextString: string);
  154. begin
  155. if CurrentTextInfo.Font = DefaultFont then
  156. begin
  157. if Currenttextinfo.direction=horizdir then
  158. begin
  159. case Currenttextinfo.horiz of
  160. centertext : XPos:=(textwidth(textstring) shr 1);
  161. lefttext : XPos:=0;
  162. righttext : XPos:=textwidth(textstring);
  163. end;
  164. case Currenttextinfo.vert of
  165. centertext : YPos:=-(textheight(textstring) shr 1);
  166. bottomtext : YPos:=-textheight(textstring);
  167. toptext : YPos:=0;
  168. end;
  169. end else
  170. begin
  171. case Currenttextinfo.horiz of
  172. centertext : XPos:=(textheight(textstring) shr 1);
  173. lefttext : XPos:=textheight(textstring);
  174. righttext : XPos:=textheight(textstring);
  175. end;
  176. case Currenttextinfo.vert of
  177. centertext : YPos:=(textwidth(textstring) shr 1);
  178. bottomtext : YPos:=0;
  179. toptext : YPos:=textwidth(textstring);
  180. end;
  181. end;
  182. end
  183. else
  184. begin
  185. if Currenttextinfo.direction=horizdir then
  186. begin
  187. case CurrentTextInfo.horiz of
  188. centertext : XPos:=(textwidth(textstring) shr 1);
  189. lefttext : XPos:=0;
  190. righttext : XPos:=textwidth(textstring);
  191. end;
  192. case CurrentTextInfo.vert of
  193. centertext : YPos:=(textheight(textstring) shr 1);
  194. bottomtext : YPos:=0;
  195. toptext : YPos:=textheight(textstring);
  196. end;
  197. end else
  198. begin
  199. case CurrentTextInfo.horiz of
  200. centertext : XPos:=(textheight(textstring) shr 1);
  201. lefttext : XPos:=0;
  202. righttext : XPos:=textheight(textstring);
  203. end;
  204. case CurrentTextInfo.vert of
  205. centertext : YPos:=(textwidth(textstring) shr 1);
  206. bottomtext : YPos:=0;
  207. toptext : YPos:=textwidth(textstring);
  208. end;
  209. end;
  210. end;
  211. end;
  212. {***************************************************************************}
  213. { Exported routines }
  214. {***************************************************************************}
  215. function RegisterBGIfont(font : pointer) : integer;
  216. var
  217. hp : pchar;
  218. b : word;
  219. i,j: longint;
  220. Header: THeader;
  221. counter: longint;
  222. FontData: pchar;
  223. FHeader: TFHeader;
  224. begin
  225. RegisterBGIfont:=grInvalidFontNum;
  226. i:=0;
  227. { Check if the font header is valid first of all }
  228. if testfont(font) then
  229. begin
  230. hp:=pchar(font);
  231. { Move to EOF in prefix header }
  232. while (hp[i] <> chr($1a)) do Inc(i);
  233. move(hp[i+1],FHeader,sizeof(TFHeader));
  234. move(hp[Prefix_Size],header,sizeof(THeader));
  235. { check if the font name is already allocated? }
  236. i:=Prefix_Size+sizeof(THeader);
  237. for b:=1 to installedfonts do
  238. begin
  239. if fonts[b].name=FHeader.Font_name then
  240. begin
  241. move(FHeader,fonts[b].PHeader,sizeof(TFHeader));
  242. move(Header,fonts[b].Header,sizeof(THeader));
  243. move(hp[i],Fonts[b].Offsets[Fonts[b].Header.First_Char],Fonts[b].Header.Nr_chars*sizeof(integer));
  244. Inc(i,Fonts[b].Header.Nr_chars*sizeof(integer));
  245. move(hp[i],Fonts[b].Widths[Fonts[b].Header.First_Char],Fonts[b].Header.Nr_chars*sizeof(byte));
  246. Inc(i,Fonts[b].Header.Nr_chars*sizeof(byte));
  247. counter:=Fonts[b].PHeader.font_size+PREFIX_SIZE-i;
  248. { allocate also space for null }
  249. GetMem(FontData,Counter+1);
  250. move(hp[i],FontData^,Counter);
  251. { Null terminate the string }
  252. FontData[counter+1] := #0;
  253. if fonts[b].header.Signature<> SIGNATURE then
  254. begin
  255. _graphResult:=grInvalidFont;
  256. Freemem(FontData, Counter+1);
  257. exit;
  258. end;
  259. fonts[b].instr:=FontData;
  260. RegisterBGIfont:=b;
  261. end;
  262. end;
  263. end
  264. else
  265. RegisterBGIFont:=grInvalidFont;
  266. end;
  267. procedure GetTextSettings(var TextInfo : TextSettingsType);
  268. begin
  269. textinfo:=currenttextinfo;
  270. end;
  271. function TextHeight(const TextString : string) : word;
  272. begin
  273. if Currenttextinfo.font=DefaultFont
  274. then TextHeight:=8*CurrentTextInfo.CharSize
  275. else
  276. TextHeight:=fonts[Currenttextinfo.font].header.org_to_cap-
  277. round(fonts[Currenttextinfo.font].header.org_to_base * CurrentYRatio) ;
  278. end;
  279. function TextWidth(const TextString : string) : word;
  280. var i,x : Integer;
  281. c : byte;
  282. begin
  283. x := 0;
  284. { if this is the default font ... }
  285. if Currenttextinfo.font = Defaultfont then
  286. TextWidth:=length(TextString)*8*CurrentTextInfo.CharSize
  287. { This is a stroked font ... }
  288. else begin
  289. for i:=1 to length(TextString) do
  290. begin
  291. c:=byte(textstring[i]);
  292. dec(c,fonts[Currenttextinfo.font].header.first_char);
  293. if (c<0) or (c>=fonts[Currenttextinfo.font].header.nr_chars) then
  294. continue;
  295. x:=x+byte(fonts[Currenttextinfo.font].widths[c]);
  296. end;
  297. TextWidth:=round(x * CurrentXRatio) ;
  298. end;
  299. end;
  300. procedure OutTextXY(x,y : integer;const TextString : string);
  301. type
  302. Tpoint = record
  303. X,Y: Integer;
  304. end;
  305. var
  306. ch: char;
  307. b1,b2 : shortint;
  308. b3 : byte;
  309. c : byte;
  310. i,j,k : longint;
  311. oldvalues : linesettingstype;
  312. nextpos : word;
  313. xpos,ypos,offs: longint;
  314. counter : longint;
  315. FontBitmap : TBitmapChar;
  316. chr: char;
  317. cnt1,cnt2 : integer;
  318. cnt3,cnt4 : integer;
  319. charsize : word;
  320. TextBuffer : array[1..sizeof(string)*2] of Tpoint;
  321. WriteMode : word;
  322. CurX, CurY : integer;
  323. begin
  324. { save current write mode }
  325. WriteMode := CurrentWriteMode;
  326. CurrentWriteMode := NormalPut;
  327. GetTextPosition(xpos,ypos,textstring);
  328. X:=X-XPos; Y:=Y+YPos;
  329. XPos:=X; YPos:=Y;
  330. CharSize := CurrentTextInfo.Charsize;
  331. if Currenttextinfo.font=DefaultFont then
  332. begin
  333. c:=length(textstring);
  334. { We must a length strength which is ZERO based }
  335. Dec(c);
  336. if CurrentTextInfo.direction=HorizDir then
  337. { Horizontal direction }
  338. begin
  339. for i:=0 to c do
  340. begin
  341. chr := TextString[i+1];
  342. xpos:=x+(i shl 3)*Charsize;
  343. { we copy the character bitmap before accessing it }
  344. { this improves speed on non optimizing compilers }
  345. { since it is one less address calculation. }
  346. Fontbitmap:=TBitmapChar(DefaultFontData[chr]);
  347. { no scaling }
  348. if CharSize = 1 then
  349. Begin
  350. for j:=0 to 7 do
  351. for k:=0 to 7 do
  352. if Fontbitmap[j,k] <> 0 then PutPixel(xpos+k,j+y,CurrentColor);
  353. end
  354. else
  355. { perform scaling of bitmap font }
  356. Begin
  357. j:=0;
  358. cnt3:=0;
  359. while j < 7 do
  360. begin
  361. { X-axis scaling }
  362. for cnt4 := 0 to charsize-1 do
  363. begin
  364. k:=0;
  365. cnt2 := 0;
  366. while k < 7 do
  367. begin
  368. for cnt1 := 0 to charsize-1 do
  369. begin
  370. If FontBitmap[j,k] <> 0 then
  371. PutPixel(xpos+cnt1+cnt2,y+cnt3+cnt4,CurrentColor);
  372. end;
  373. Inc(k);
  374. Inc(cnt2,charsize);
  375. end;
  376. end;
  377. Inc(j);
  378. Inc(cnt3,charsize);
  379. end;
  380. end;
  381. end;
  382. end
  383. else
  384. { Vertical direction }
  385. begin
  386. for i:=0 to c do
  387. begin
  388. chr := TextString[i+1];
  389. Fontbitmap:=TBitmapChar(DefaultFontData[chr]);
  390. ypos := y-(i shl 3)*CharSize;
  391. { no scaling }
  392. if CharSize = 1 then
  393. Begin
  394. for j:=0 to 7 do
  395. for k:=0 to 7 do
  396. if Fontbitmap[j,k] <> 0 then PutPixel(xpos+j,ypos-k,
  397. CurrentColor);
  398. end
  399. else
  400. { perform scaling of bitmap font }
  401. Begin
  402. j:=0;
  403. cnt3:=0;
  404. while j < 7 do
  405. begin
  406. { X-axis scaling }
  407. for cnt4 := 0 to charsize-1 do
  408. begin
  409. k:=0;
  410. cnt2 := 0;
  411. while k < 7 do
  412. begin
  413. for cnt1 := 0 to charsize-1 do
  414. begin
  415. If FontBitmap[j,k] <> 0 then
  416. PutPixel(xpos+cnt3-cnt4,ypos+cnt1-cnt2,
  417. CurrentColor);
  418. end;
  419. Inc(k);
  420. Inc(cnt2,charsize);
  421. end;
  422. end;
  423. Inc(j);
  424. Inc(cnt3,charsize);
  425. end;
  426. end;
  427. end;
  428. end;
  429. end else
  430. { This is a stroked font which is already loaded into memory }
  431. begin
  432. getlinesettings(oldvalues);
  433. { reset line style to defaults }
  434. setlinestyle(solidln,oldvalues.pattern,normwidth);
  435. if Currenttextinfo.direction=vertdir then
  436. xpos:=xpos + Textheight(textstring);
  437. CurX:=xpos; CurY:=ypos; x:=xpos; y:=ypos;
  438. for i:=1 to length(textstring) do
  439. begin
  440. c:=byte(textstring[i]);
  441. Stroke_Count[c] := unpack( fonts[CurrentTextInfo.font].instr,
  442. fonts[CurrentTextInfo.font].Offsets[c], Strokes );
  443. counter:=0;
  444. while true do
  445. begin
  446. if CurrentTextInfo.direction=VertDir then
  447. begin
  448. xpos:=x-round(Strokes[counter].Y*CurrentXRatio);
  449. ypos:=y-round(Strokes[counter].X*CurrentYRatio);
  450. end
  451. else
  452. begin
  453. xpos:=x+round(Strokes[counter].X*CurrentXRatio) ;
  454. ypos:=y-round(Strokes[counter].Y*CurrentYRatio) ;
  455. end;
  456. case opcodes(Strokes[counter].opcode) of
  457. _END_OF_CHAR: break;
  458. _DO_SCAN: begin
  459. { Currently unsupported };
  460. end;
  461. _MOVE : Begin
  462. CurX := XPos;
  463. CurY := YPos;
  464. end;
  465. _DRAW: Begin
  466. Line(CurX,CurY,xpos,ypos);
  467. CurX:=xpos;
  468. CurY:=ypos;
  469. end;
  470. else
  471. Begin
  472. end;
  473. end;
  474. Inc(counter);
  475. end; { end while }
  476. if Currenttextinfo.direction=VertDir then
  477. y:=y-round(byte(fonts[CurrenttextInfo.font].widths[c])*CurrentXRatio)
  478. else
  479. x:=x+round(byte(fonts[Currenttextinfo.font].widths[c])*CurrentXRatio) ;
  480. end;
  481. setlinestyle( oldvalues.linestyle, oldvalues.pattern, oldvalues.thickness);
  482. end;
  483. { restore write mode }
  484. CurrentWriteMode := WriteMode;
  485. end;
  486. procedure OutText(const TextString : string);
  487. var x,y:integer;
  488. begin
  489. { Save CP }
  490. x:=CurrentX;
  491. y:=CurrentY;
  492. OutTextXY(CurrentX,CurrentY,TextString);
  493. { If the direction is Horizontal and the justification left }
  494. { then and only then do we update the CP }
  495. if (Currenttextinfo.direction=HorizDir) and
  496. (Currenttextinfo.horiz=LeftText) then
  497. inc(x,textwidth(TextString));
  498. { Update the CP }
  499. CurrentX := X;
  500. CurrentY := Y;
  501. end;
  502. procedure SetTextJustify(horiz,vert : word);
  503. begin
  504. if (horiz<0) or (horiz>2) or
  505. (vert<0) or (vert>2) then
  506. begin
  507. _graphresult:=grError;
  508. exit;
  509. end;
  510. Currenttextinfo.horiz:=horiz;
  511. Currenttextinfo.vert:=vert;
  512. end;
  513. procedure SetTextStyle(font,direction : word;charsize : word);
  514. var
  515. f : file;
  516. Prefix: array[0..Prefix_Size-1] of char; {* File Prefix Holder *}
  517. Length, Current: longint;
  518. FontData: Pchar;
  519. Base: longint;
  520. hp : pchar;
  521. i : longint;
  522. begin
  523. if font>installedfonts then
  524. begin
  525. _graphresult:=grInvalidFontNum;
  526. exit;
  527. end;
  528. Currenttextinfo.font:=font;
  529. if (direction<>HorizDir) and (direction<>VertDir) then
  530. direction:=HorizDir;
  531. Currenttextinfo.direction:=direction;
  532. { According to the Turbo Pascal programmer's reference }
  533. { maximum charsize for bitmapped font is 10 }
  534. if (CurrentTextInfo.Font = DefaultFont) and (Charsize > 10) then
  535. Currenttextinfo.charsize:=10
  536. else
  537. Currenttextinfo.charsize:=charsize;
  538. { This is only valid for stroked fonts }
  539. if (charsize <> usercharsize) then
  540. begin
  541. CurrentXRatio := charsize / 4;
  542. CurrentYRatio := charsize / 4;
  543. end;
  544. { if this is a stroked font then load it if not already loaded }
  545. { into memory... }
  546. if (font>DefaultFont) and not assigned(fonts[font].instr) then
  547. begin
  548. assign(f,bgipath+fonts[font].name+'.CHR');
  549. reset(f,1);
  550. if ioresult<>0 then
  551. begin
  552. _graphresult:=grFontNotFound;
  553. Currenttextinfo.font:=DefaultFont;
  554. exit;
  555. end;
  556. {* Read in the file prefix *}
  557. BlockRead(F, Prefix, Prefix_Size);
  558. hp:=Prefix;
  559. i:=0;
  560. while (hp[i] <> chr($1a)) do Inc(i);
  561. move(hp[i+1],fonts[font].PHeader,sizeof(TFHeader));
  562. (* Read in the Header file *)
  563. BlockRead(F,fonts[font].Header,Sizeof(THeader));
  564. Base := FilePos(F); {* Remember the address of table*}
  565. BlockRead(F,Fonts[font].Offsets[Fonts[font].Header.First_Char],Fonts[font].Header.Nr_chars*sizeof(integer));
  566. {* Load the character width table into memory. *}
  567. base := filePos( f );
  568. BlockRead(F,Fonts[font].Widths[Fonts[font].Header.First_Char],Fonts[font].Header.Nr_chars*sizeof(byte));
  569. {* Determine the length of the stroke database. *}
  570. current := FilePos( f ); {* Current file location *}
  571. Seek( f, FileSize(F)); {* Go to the end of the file *}
  572. length := FilePos( f ); {* Get the file length *}
  573. Seek( f, current); {* Restore old file location *}
  574. {* Load the stroke database. *}
  575. { also allocate space for Null character }
  576. Getmem(FontData, Length+1); {* Create space for font data *}
  577. BlockRead(F, FontData^, length-current); {* Load the stroke data *}
  578. FontData[length-current+1] := #0;
  579. if fonts[font].header.Signature<> SIGNATURE then
  580. begin
  581. _graphResult:=grInvalidFont;
  582. Currenttextinfo.font:=DefaultFont;
  583. Freemem(FontData, Length+1);
  584. exit;
  585. end;
  586. fonts[font].instr:=FontData;
  587. if not testfont(Prefix) then
  588. begin
  589. _graphresult:=grInvalidFont;
  590. Currenttextinfo.font:=DefaultFont;
  591. Freemem(FontData, Length+1);
  592. end;
  593. close(f);
  594. end;
  595. end;
  596. procedure SetUserCharSize(Multx,Divx,Multy,Divy : word);
  597. begin
  598. CurrentXRatio := MultX / DivX;
  599. CurrentYRatio := MultY / DivY;
  600. end;
  601. {
  602. $Log$
  603. Revision 1.4 1999-07-12 13:27:16 jonas
  604. + added Log and Id tags
  605. * added first FPC support, only VGA works to some extend for now
  606. * use -dasmgraph to use assembler routines, otherwise Pascal
  607. equivalents are used
  608. * use -dsupportVESA to support VESA (crashes under FPC for now)
  609. * only dispose vesainfo at closegrph if a vesa card was detected
  610. * changed int32 to longint (int32 is not declared under FPC)
  611. * changed the declaration of almost every procedure in graph.inc to
  612. "far;" becquse otherwise you can't assign them to procvars under TP
  613. real mode (but unexplainable "data segnment too large" errors prevent
  614. it from working under real mode anyway)
  615. }