gtext.inc 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  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: shortint; { Height from origin to top of capitol }
  43. org_to_base:shortint; { Height from origin to baseline }
  44. org_to_dec: shortint; { 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)+1;
  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:=Trunc((fonts[Currenttextinfo.font].header.org_to_cap-
  277. fonts[Currenttextinfo.font].header.org_to_dec) * 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-fonts[Currenttextinfo.font].header.first_char>=
  294. fonts[Currenttextinfo.font].header.nr_chars) then
  295. continue;
  296. x:=x+byte(fonts[Currenttextinfo.font].widths[c]);
  297. end;
  298. TextWidth:=round(x * CurrentXRatio) ;
  299. end;
  300. end;
  301. procedure OutTextXY(x,y : integer;const TextString : string);
  302. type
  303. Tpoint = record
  304. X,Y: Integer;
  305. end;
  306. var
  307. ch: char;
  308. b1,b2 : shortint;
  309. b3 : byte;
  310. i,j,k,c : 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. { if c is a byte and length is zero, this is }
  336. { dangerous, fixed }
  337. Dec(c);
  338. if CurrentTextInfo.direction=HorizDir then
  339. { Horizontal direction }
  340. begin
  341. for i:=0 to c do
  342. begin
  343. chr := TextString[i+1];
  344. xpos:=x+(i shl 3)*Charsize;
  345. { we copy the character bitmap before accessing it }
  346. { this improves speed on non optimizing compilers }
  347. { since it is one less address calculation. }
  348. Fontbitmap:=TBitmapChar(DefaultFontData[chr]);
  349. { no scaling }
  350. if CharSize = 1 then
  351. Begin
  352. for j:=0 to 7 do
  353. for k:=0 to 7 do
  354. if Fontbitmap[j,k] <> 0 then PutPixel(xpos+k,j+y,CurrentColor);
  355. end
  356. else
  357. { perform scaling of bitmap font }
  358. Begin
  359. j:=0;
  360. cnt3:=0;
  361. while j < 7 do
  362. begin
  363. { X-axis scaling }
  364. for cnt4 := 0 to charsize-1 do
  365. begin
  366. k:=0;
  367. cnt2 := 0;
  368. while k < 7 do
  369. begin
  370. for cnt1 := 0 to charsize-1 do
  371. begin
  372. If FontBitmap[j,k] <> 0 then
  373. PutPixel(xpos+cnt1+cnt2,y+cnt3+cnt4,CurrentColor);
  374. end;
  375. Inc(k);
  376. Inc(cnt2,charsize);
  377. end;
  378. end;
  379. Inc(j);
  380. Inc(cnt3,charsize);
  381. end;
  382. end;
  383. end;
  384. end
  385. else
  386. { Vertical direction }
  387. begin
  388. for i:=0 to c do
  389. begin
  390. chr := TextString[i+1];
  391. Fontbitmap:=TBitmapChar(DefaultFontData[chr]);
  392. ypos := y-(i shl 3)*CharSize;
  393. { no scaling }
  394. if CharSize = 1 then
  395. Begin
  396. for j:=0 to 7 do
  397. for k:=0 to 7 do
  398. if Fontbitmap[j,k] <> 0 then PutPixel(xpos+j,ypos-k,
  399. CurrentColor);
  400. end
  401. else
  402. { perform scaling of bitmap font }
  403. Begin
  404. j:=0;
  405. cnt3:=0;
  406. while j < 7 do
  407. begin
  408. { X-axis scaling }
  409. for cnt4 := 0 to charsize-1 do
  410. begin
  411. k:=0;
  412. cnt2 := 0;
  413. while k < 7 do
  414. begin
  415. for cnt1 := 0 to charsize-1 do
  416. begin
  417. If FontBitmap[j,k] <> 0 then
  418. PutPixel(xpos+cnt3-cnt4,ypos+cnt1-cnt2,
  419. CurrentColor);
  420. end;
  421. Inc(k);
  422. Inc(cnt2,charsize);
  423. end;
  424. end;
  425. Inc(j);
  426. Inc(cnt3,charsize);
  427. end;
  428. end;
  429. end;
  430. end;
  431. end else
  432. { This is a stroked font which is already loaded into memory }
  433. begin
  434. getlinesettings(oldvalues);
  435. { reset line style to defaults }
  436. setlinestyle(solidln,oldvalues.pattern,normwidth);
  437. if Currenttextinfo.direction=vertdir then
  438. xpos:=xpos + Textheight(textstring);
  439. CurX:=xpos; CurY:=ypos; x:=xpos; y:=ypos;
  440. for i:=1 to length(textstring) do
  441. begin
  442. c:=byte(textstring[i]);
  443. Stroke_Count[c] := unpack( fonts[CurrentTextInfo.font].instr,
  444. fonts[CurrentTextInfo.font].Offsets[c], Strokes );
  445. counter:=0;
  446. while true do
  447. begin
  448. if CurrentTextInfo.direction=VertDir then
  449. begin
  450. xpos:=x-round(Strokes[counter].Y*CurrentXRatio);
  451. ypos:=y-round(Strokes[counter].X*CurrentYRatio);
  452. end
  453. else
  454. begin
  455. xpos:=x+round(Strokes[counter].X*CurrentXRatio) ;
  456. ypos:=y-round(Strokes[counter].Y*CurrentYRatio) ;
  457. end;
  458. case opcodes(Strokes[counter].opcode) of
  459. _END_OF_CHAR: break;
  460. _DO_SCAN: begin
  461. { Currently unsupported };
  462. end;
  463. _MOVE : Begin
  464. CurX := XPos;
  465. CurY := YPos;
  466. end;
  467. _DRAW: Begin
  468. Line(CurX,CurY,xpos,ypos);
  469. CurX:=xpos;
  470. CurY:=ypos;
  471. end;
  472. else
  473. Begin
  474. end;
  475. end;
  476. Inc(counter);
  477. end; { end while }
  478. if Currenttextinfo.direction=VertDir then
  479. y:=y-round(byte(fonts[CurrenttextInfo.font].widths[c])*CurrentXRatio)
  480. else
  481. x:=x+round(byte(fonts[Currenttextinfo.font].widths[c])*CurrentXRatio) ;
  482. end;
  483. setlinestyle( oldvalues.linestyle, oldvalues.pattern, oldvalues.thickness);
  484. end;
  485. { restore write mode }
  486. CurrentWriteMode := WriteMode;
  487. end;
  488. procedure OutText(const TextString : string);
  489. var x,y:integer;
  490. begin
  491. { Save CP }
  492. x:=CurrentX;
  493. y:=CurrentY;
  494. OutTextXY(CurrentX,CurrentY,TextString);
  495. { If the direction is Horizontal and the justification left }
  496. { then and only then do we update the CP }
  497. if (Currenttextinfo.direction=HorizDir) and
  498. (Currenttextinfo.horiz=LeftText) then
  499. inc(x,textwidth(TextString));
  500. { Update the CP }
  501. CurrentX := X;
  502. CurrentY := Y;
  503. end;
  504. procedure SetTextJustify(horiz,vert : word);
  505. begin
  506. if (horiz<0) or (horiz>2) or
  507. (vert<0) or (vert>2) then
  508. begin
  509. _graphresult:=grError;
  510. exit;
  511. end;
  512. Currenttextinfo.horiz:=horiz;
  513. Currenttextinfo.vert:=vert;
  514. end;
  515. procedure SetTextStyle(font,direction : word;charsize : word);
  516. var
  517. f : file;
  518. Prefix: array[0..Prefix_Size-1] of char; {* File Prefix Holder *}
  519. Length, Current: longint;
  520. FontData: Pchar;
  521. Base: longint;
  522. hp : pchar;
  523. i : longint;
  524. begin
  525. if font>installedfonts then
  526. begin
  527. _graphresult:=grInvalidFontNum;
  528. exit;
  529. end;
  530. Currenttextinfo.font:=font;
  531. if (direction<>HorizDir) and (direction<>VertDir) then
  532. direction:=HorizDir;
  533. Currenttextinfo.direction:=direction;
  534. { According to the Turbo Pascal programmer's reference }
  535. { maximum charsize for bitmapped font is 10 }
  536. if (CurrentTextInfo.Font = DefaultFont) and (Charsize > 10) then
  537. Currenttextinfo.charsize:=10
  538. else if charsize<1 then
  539. Currenttextinfo.charsize:=1
  540. else
  541. Currenttextinfo.charsize:=charsize;
  542. { This is only valid for stroked fonts }
  543. {$ifdef logging}
  544. LogLn('(org_to_cap - org_to_dec): ' + strf(
  545. fonts[Currenttextinfo.font].header.org_to_cap-
  546. fonts[Currenttextinfo.font].header.org_to_dec));
  547. {$endif logging}
  548. if (charsize <> usercharsize) then
  549. Case CharSize of
  550. 1: Begin
  551. CurrentXRatio := 0.55;
  552. CurrentYRatio := 0.55;
  553. End;
  554. 2: Begin
  555. CurrentXRatio := 0.65;
  556. CurrentYRatio := 0.65;
  557. End;
  558. 3: Begin
  559. CurrentXRatio := 0.75;
  560. CurrentYRatio := 0.75;
  561. End;
  562. 4: Begin
  563. CurrentXRatio := 1.0;
  564. CurrentYRatio := 1.0;
  565. End;
  566. 5: Begin
  567. CurrentXRatio := 1.3;
  568. CurrentYRatio := 1.3;
  569. End;
  570. 6: Begin
  571. CurrentXRatio := 1.65;
  572. CurrentYRatio := 1.65
  573. End;
  574. 7: Begin
  575. CurrentXRatio := 2.0;
  576. CurrentYRatio := 2.0;
  577. End;
  578. 8: Begin
  579. CurrentXRatio := 2.5;
  580. CurrentYRatio := 2.5;
  581. End;
  582. 9: Begin
  583. CurrentXRatio := 3.0;
  584. CurrentYRatio := 3.0;
  585. End;
  586. 10: Begin
  587. CurrentXRatio := 4.0;
  588. CurrentYRatio := 4.0;
  589. End
  590. End;
  591. { if this is a stroked font then load it if not already loaded }
  592. { into memory... }
  593. if (font>DefaultFont) and not assigned(fonts[font].instr) then
  594. begin
  595. assign(f,bgipath+fonts[font].name+'.CHR');
  596. reset(f,1);
  597. if ioresult<>0 then
  598. begin
  599. _graphresult:=grFontNotFound;
  600. Currenttextinfo.font:=DefaultFont;
  601. exit;
  602. end;
  603. {* Read in the file prefix *}
  604. BlockRead(F, Prefix, Prefix_Size);
  605. hp:=Prefix;
  606. i:=0;
  607. while (hp[i] <> chr($1a)) do Inc(i);
  608. move(hp[i+1],fonts[font].PHeader,sizeof(TFHeader));
  609. (* Read in the Header file *)
  610. BlockRead(F,fonts[font].Header,Sizeof(THeader));
  611. Base := FilePos(F); {* Remember the address of table*}
  612. BlockRead(F,Fonts[font].Offsets[Fonts[font].Header.First_Char],Fonts[font].Header.Nr_chars*sizeof(integer));
  613. {* Load the character width table into memory. *}
  614. base := filePos( f );
  615. BlockRead(F,Fonts[font].Widths[Fonts[font].Header.First_Char],Fonts[font].Header.Nr_chars*sizeof(byte));
  616. {* Determine the length of the stroke database. *}
  617. current := FilePos( f ); {* Current file location *}
  618. Seek( f, FileSize(F)); {* Go to the end of the file *}
  619. length := FilePos( f ); {* Get the file length *}
  620. Seek( f, current); {* Restore old file location *}
  621. {* Load the stroke database. *}
  622. { also allocate space for Null character }
  623. Getmem(FontData, Length+1); {* Create space for font data *}
  624. BlockRead(F, FontData^, length-current); {* Load the stroke data *}
  625. FontData[length-current+1] := #0;
  626. if fonts[font].header.Signature<> SIGNATURE then
  627. begin
  628. _graphResult:=grInvalidFont;
  629. Currenttextinfo.font:=DefaultFont;
  630. Freemem(FontData, Length+1);
  631. exit;
  632. end;
  633. fonts[font].instr:=FontData;
  634. if not testfont(Prefix) then
  635. begin
  636. _graphresult:=grInvalidFont;
  637. Currenttextinfo.font:=DefaultFont;
  638. Freemem(FontData, Length+1);
  639. end;
  640. close(f);
  641. end;
  642. end;
  643. procedure SetUserCharSize(Multx,Divx,Multy,Divy : word);
  644. begin
  645. CurrentXRatio := MultX / DivX;
  646. CurrentYRatio := MultY / DivY;
  647. end;
  648. {
  649. $Log$
  650. Revision 1.3 1999-09-22 14:54:11 jonas
  651. * changed ratios so font sizes on screen are the same as with TP
  652. * SetUserCharSize must also use / instead of DIV
  653. Revision 1.2 1999/09/22 13:30:52 jonas
  654. * changed org_to_cap, org_to_dec and org_to_base to shortint (from
  655. Michael Knapp's gxtext unit, part of the GraphiX package)
  656. * in settextstyle, the calculation of the ratios must be done
  657. with /, not DIV!!
  658. Revision 1.1 1999/09/22 13:13:36 jonas
  659. * renamed text.inc -> gtext.inc to avoid conflict with system unit
  660. * fixed textwidth
  661. * isgraphmode now gets properly updated, so mode restoring works
  662. again
  663. Revision 1.7 1999/09/12 17:29:00 jonas
  664. * several changes to internalellipse to make it faster
  665. and to make sure it updates the ArcCall correctly
  666. (not yet done for width = 3)
  667. * Arc mostly works now, only sometimes an endless loop, don't know
  668. why
  669. Revision 1.6 1999/09/12 08:02:22 florian
  670. * fixed outtext(''), c was a byte, this leads to an underflow and
  671. garbage was written
  672. Revision 1.5 1999/07/26 09:38:43 florian
  673. * bar: y2 can be less y1, fixed
  674. * settextstyle: charsize can be 0, must be changed into 1
  675. Revision 1.4 1999/07/12 13:27:16 jonas
  676. + added Log and Id tags
  677. * added first FPC support, only VGA works to some extend for now
  678. * use -dasmgraph to use assembler routines, otherwise Pascal
  679. equivalents are used
  680. * use -dsupportVESA to support VESA (crashes under FPC for now)
  681. * only dispose vesainfo at closegrph if a vesa card was detected
  682. * changed int32 to longint (int32 is not declared under FPC)
  683. * changed the declaration of almost every procedure in graph.inc to
  684. "far;" becquse otherwise you can't assign them to procvars under TP
  685. real mode (but unexplainable "data segnment too large" errors prevent
  686. it from working under real mode anyway)
  687. }