text.inc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  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. i,j,k,c : longint;
  310. oldvalues : linesettingstype;
  311. nextpos : word;
  312. xpos,ypos,offs: longint;
  313. counter : longint;
  314. FontBitmap : TBitmapChar;
  315. chr: char;
  316. cnt1,cnt2 : integer;
  317. cnt3,cnt4 : integer;
  318. charsize : word;
  319. TextBuffer : array[1..sizeof(string)*2] of Tpoint;
  320. WriteMode : word;
  321. CurX, CurY : integer;
  322. begin
  323. { save current write mode }
  324. WriteMode := CurrentWriteMode;
  325. CurrentWriteMode := NormalPut;
  326. GetTextPosition(xpos,ypos,textstring);
  327. X:=X-XPos; Y:=Y+YPos;
  328. XPos:=X; YPos:=Y;
  329. CharSize := CurrentTextInfo.Charsize;
  330. if Currenttextinfo.font=DefaultFont then
  331. begin
  332. c:=length(textstring);
  333. { We must a length strength which is ZERO based }
  334. { if c is a byte and length is zero, this is }
  335. { dangerous, fixed }
  336. Dec(c);
  337. if CurrentTextInfo.direction=HorizDir then
  338. { Horizontal direction }
  339. begin
  340. for i:=0 to c do
  341. begin
  342. chr := TextString[i+1];
  343. xpos:=x+(i shl 3)*Charsize;
  344. { we copy the character bitmap before accessing it }
  345. { this improves speed on non optimizing compilers }
  346. { since it is one less address calculation. }
  347. Fontbitmap:=TBitmapChar(DefaultFontData[chr]);
  348. { no scaling }
  349. if CharSize = 1 then
  350. Begin
  351. for j:=0 to 7 do
  352. for k:=0 to 7 do
  353. if Fontbitmap[j,k] <> 0 then PutPixel(xpos+k,j+y,CurrentColor);
  354. end
  355. else
  356. { perform scaling of bitmap font }
  357. Begin
  358. j:=0;
  359. cnt3:=0;
  360. while j < 7 do
  361. begin
  362. { X-axis scaling }
  363. for cnt4 := 0 to charsize-1 do
  364. begin
  365. k:=0;
  366. cnt2 := 0;
  367. while k < 7 do
  368. begin
  369. for cnt1 := 0 to charsize-1 do
  370. begin
  371. If FontBitmap[j,k] <> 0 then
  372. PutPixel(xpos+cnt1+cnt2,y+cnt3+cnt4,CurrentColor);
  373. end;
  374. Inc(k);
  375. Inc(cnt2,charsize);
  376. end;
  377. end;
  378. Inc(j);
  379. Inc(cnt3,charsize);
  380. end;
  381. end;
  382. end;
  383. end
  384. else
  385. { Vertical direction }
  386. begin
  387. for i:=0 to c do
  388. begin
  389. chr := TextString[i+1];
  390. Fontbitmap:=TBitmapChar(DefaultFontData[chr]);
  391. ypos := y-(i shl 3)*CharSize;
  392. { no scaling }
  393. if CharSize = 1 then
  394. Begin
  395. for j:=0 to 7 do
  396. for k:=0 to 7 do
  397. if Fontbitmap[j,k] <> 0 then PutPixel(xpos+j,ypos-k,
  398. CurrentColor);
  399. end
  400. else
  401. { perform scaling of bitmap font }
  402. Begin
  403. j:=0;
  404. cnt3:=0;
  405. while j < 7 do
  406. begin
  407. { X-axis scaling }
  408. for cnt4 := 0 to charsize-1 do
  409. begin
  410. k:=0;
  411. cnt2 := 0;
  412. while k < 7 do
  413. begin
  414. for cnt1 := 0 to charsize-1 do
  415. begin
  416. If FontBitmap[j,k] <> 0 then
  417. PutPixel(xpos+cnt3-cnt4,ypos+cnt1-cnt2,
  418. CurrentColor);
  419. end;
  420. Inc(k);
  421. Inc(cnt2,charsize);
  422. end;
  423. end;
  424. Inc(j);
  425. Inc(cnt3,charsize);
  426. end;
  427. end;
  428. end;
  429. end;
  430. end else
  431. { This is a stroked font which is already loaded into memory }
  432. begin
  433. getlinesettings(oldvalues);
  434. { reset line style to defaults }
  435. setlinestyle(solidln,oldvalues.pattern,normwidth);
  436. if Currenttextinfo.direction=vertdir then
  437. xpos:=xpos + Textheight(textstring);
  438. CurX:=xpos; CurY:=ypos; x:=xpos; y:=ypos;
  439. for i:=1 to length(textstring) do
  440. begin
  441. c:=byte(textstring[i]);
  442. Stroke_Count[c] := unpack( fonts[CurrentTextInfo.font].instr,
  443. fonts[CurrentTextInfo.font].Offsets[c], Strokes );
  444. counter:=0;
  445. while true do
  446. begin
  447. if CurrentTextInfo.direction=VertDir then
  448. begin
  449. xpos:=x-round(Strokes[counter].Y*CurrentXRatio);
  450. ypos:=y-round(Strokes[counter].X*CurrentYRatio);
  451. end
  452. else
  453. begin
  454. xpos:=x+round(Strokes[counter].X*CurrentXRatio) ;
  455. ypos:=y-round(Strokes[counter].Y*CurrentYRatio) ;
  456. end;
  457. case opcodes(Strokes[counter].opcode) of
  458. _END_OF_CHAR: break;
  459. _DO_SCAN: begin
  460. { Currently unsupported };
  461. end;
  462. _MOVE : Begin
  463. CurX := XPos;
  464. CurY := YPos;
  465. end;
  466. _DRAW: Begin
  467. Line(CurX,CurY,xpos,ypos);
  468. CurX:=xpos;
  469. CurY:=ypos;
  470. end;
  471. else
  472. Begin
  473. end;
  474. end;
  475. Inc(counter);
  476. end; { end while }
  477. if Currenttextinfo.direction=VertDir then
  478. y:=y-round(byte(fonts[CurrenttextInfo.font].widths[c])*CurrentXRatio)
  479. else
  480. x:=x+round(byte(fonts[Currenttextinfo.font].widths[c])*CurrentXRatio) ;
  481. end;
  482. setlinestyle( oldvalues.linestyle, oldvalues.pattern, oldvalues.thickness);
  483. end;
  484. { restore write mode }
  485. CurrentWriteMode := WriteMode;
  486. end;
  487. procedure OutText(const TextString : string);
  488. var x,y:integer;
  489. begin
  490. { Save CP }
  491. x:=CurrentX;
  492. y:=CurrentY;
  493. OutTextXY(CurrentX,CurrentY,TextString);
  494. { If the direction is Horizontal and the justification left }
  495. { then and only then do we update the CP }
  496. if (Currenttextinfo.direction=HorizDir) and
  497. (Currenttextinfo.horiz=LeftText) then
  498. inc(x,textwidth(TextString));
  499. { Update the CP }
  500. CurrentX := X;
  501. CurrentY := Y;
  502. end;
  503. procedure SetTextJustify(horiz,vert : word);
  504. begin
  505. if (horiz<0) or (horiz>2) or
  506. (vert<0) or (vert>2) then
  507. begin
  508. _graphresult:=grError;
  509. exit;
  510. end;
  511. Currenttextinfo.horiz:=horiz;
  512. Currenttextinfo.vert:=vert;
  513. end;
  514. procedure SetTextStyle(font,direction : word;charsize : word);
  515. var
  516. f : file;
  517. Prefix: array[0..Prefix_Size-1] of char; {* File Prefix Holder *}
  518. Length, Current: longint;
  519. FontData: Pchar;
  520. Base: longint;
  521. hp : pchar;
  522. i : longint;
  523. begin
  524. if font>installedfonts then
  525. begin
  526. _graphresult:=grInvalidFontNum;
  527. exit;
  528. end;
  529. Currenttextinfo.font:=font;
  530. if (direction<>HorizDir) and (direction<>VertDir) then
  531. direction:=HorizDir;
  532. Currenttextinfo.direction:=direction;
  533. { According to the Turbo Pascal programmer's reference }
  534. { maximum charsize for bitmapped font is 10 }
  535. if (CurrentTextInfo.Font = DefaultFont) and (Charsize > 10) then
  536. Currenttextinfo.charsize:=10
  537. else if charsize<1 then
  538. Currenttextinfo.charsize:=1
  539. else
  540. Currenttextinfo.charsize:=charsize;
  541. { This is only valid for stroked fonts }
  542. if (charsize <> usercharsize) then
  543. begin
  544. CurrentXRatio := charsize div 4;
  545. CurrentYRatio := charsize div 4;
  546. end;
  547. { if this is a stroked font then load it if not already loaded }
  548. { into memory... }
  549. if (font>DefaultFont) and not assigned(fonts[font].instr) then
  550. begin
  551. assign(f,bgipath+fonts[font].name+'.CHR');
  552. reset(f,1);
  553. if ioresult<>0 then
  554. begin
  555. _graphresult:=grFontNotFound;
  556. Currenttextinfo.font:=DefaultFont;
  557. exit;
  558. end;
  559. {* Read in the file prefix *}
  560. BlockRead(F, Prefix, Prefix_Size);
  561. hp:=Prefix;
  562. i:=0;
  563. while (hp[i] <> chr($1a)) do Inc(i);
  564. move(hp[i+1],fonts[font].PHeader,sizeof(TFHeader));
  565. (* Read in the Header file *)
  566. BlockRead(F,fonts[font].Header,Sizeof(THeader));
  567. Base := FilePos(F); {* Remember the address of table*}
  568. BlockRead(F,Fonts[font].Offsets[Fonts[font].Header.First_Char],Fonts[font].Header.Nr_chars*sizeof(integer));
  569. {* Load the character width table into memory. *}
  570. base := filePos( f );
  571. BlockRead(F,Fonts[font].Widths[Fonts[font].Header.First_Char],Fonts[font].Header.Nr_chars*sizeof(byte));
  572. {* Determine the length of the stroke database. *}
  573. current := FilePos( f ); {* Current file location *}
  574. Seek( f, FileSize(F)); {* Go to the end of the file *}
  575. length := FilePos( f ); {* Get the file length *}
  576. Seek( f, current); {* Restore old file location *}
  577. {* Load the stroke database. *}
  578. { also allocate space for Null character }
  579. Getmem(FontData, Length+1); {* Create space for font data *}
  580. BlockRead(F, FontData^, length-current); {* Load the stroke data *}
  581. FontData[length-current+1] := #0;
  582. if fonts[font].header.Signature<> SIGNATURE then
  583. begin
  584. _graphResult:=grInvalidFont;
  585. Currenttextinfo.font:=DefaultFont;
  586. Freemem(FontData, Length+1);
  587. exit;
  588. end;
  589. fonts[font].instr:=FontData;
  590. if not testfont(Prefix) then
  591. begin
  592. _graphresult:=grInvalidFont;
  593. Currenttextinfo.font:=DefaultFont;
  594. Freemem(FontData, Length+1);
  595. end;
  596. close(f);
  597. end;
  598. end;
  599. procedure SetUserCharSize(Multx,Divx,Multy,Divy : word);
  600. begin
  601. CurrentXRatio := MultX div DivX;
  602. CurrentYRatio := MultY div DivY;
  603. end;
  604. {
  605. $Log$
  606. Revision 1.7 1999-09-12 17:29:00 jonas
  607. * several changes to internalellipse to make it faster
  608. and to make sure it updates the ArcCall correctly
  609. (not yet done for width = 3)
  610. * Arc mostly works now, only sometimes an endless loop, don't know
  611. why
  612. Revision 1.6 1999/09/12 08:02:22 florian
  613. * fixed outtext(''), c was a byte, this leads to an underflow and
  614. garbage was written
  615. Revision 1.5 1999/07/26 09:38:43 florian
  616. * bar: y2 can be less y1, fixed
  617. * settextstyle: charsize can be 0, must be changed into 1
  618. Revision 1.4 1999/07/12 13:27:16 jonas
  619. + added Log and Id tags
  620. * added first FPC support, only VGA works to some extend for now
  621. * use -dasmgraph to use assembler routines, otherwise Pascal
  622. equivalents are used
  623. * use -dsupportVESA to support VESA (crashes under FPC for now)
  624. * only dispose vesainfo at closegrph if a vesa card was detected
  625. * changed int32 to longint (int32 is not declared under FPC)
  626. * changed the declaration of almost every procedure in graph.inc to
  627. "far;" becquse otherwise you can't assign them to procvars under TP
  628. real mode (but unexplainable "data segnment too large" errors prevent
  629. it from working under real mode anyway)
  630. }