gtext.inc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 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. { Prefix header of Font file }
  21. { PFHeader = ^TFHeader;}
  22. TFHeader = packed record
  23. header_size: word; {* Version 2.0 Header Format *}
  24. font_name: array[1..4] of char;
  25. font_size: word; {* Size in byte of file *}
  26. font_major: byte; {* Driver Version Information *}
  27. font_minor: byte;
  28. min_major: byte; {* BGI Revision Information *}
  29. min_minor: byte;
  30. end;
  31. { Font record information }
  32. { PHeader = ^THeader;}
  33. THeader = packed record
  34. Signature: char; { signature byte }
  35. Nr_chars: smallint; { number of characters in file }
  36. Reserved: byte;
  37. First_char: byte; { first character in file }
  38. cdefs : smallint; { offset to character definitions }
  39. scan_flag: byte; { TRUE if char is scanable }
  40. org_to_cap: shortint; { Height from origin to top of capitol }
  41. org_to_base:shortint; { Height from origin to baseline }
  42. org_to_dec: shortint; { Height from origin to bot of decender }
  43. _reserved: array[1..4] of char;
  44. Unused: byte;
  45. end;
  46. TOffsetTable =array[0..MaxChars] of smallint;
  47. TWidthTable =array[0..MaxChars] of byte;
  48. tfontrec = packed record
  49. name : string[8];
  50. header : THeader; { font header }
  51. pheader : TFHeader; { prefix header }
  52. offsets : TOffsetTable;
  53. widths : TWidthTable;
  54. instrlength: longint; { length of instr, because instr can }
  55. instr : pchar; { contain null characters }
  56. end;
  57. { pStroke = ^TStroke;}
  58. TStroke = packed record
  59. opcode: byte;
  60. x: smallint; { relative x offset character }
  61. y: smallint; { relative y offset character }
  62. end;
  63. TStrokes = Array[0..1000] of TStroke;
  64. opcodes = (_END_OF_CHAR, _DO_SCAN, _MOVE, _DRAW);
  65. var
  66. fonts : array[1..maxfonts] of tfontrec;
  67. Strokes: TStrokes; {* Stroke Data Base *}
  68. { Stroke_count: Array[0..MaxChars] of smallint;} {* Stroke Count Table *}
  69. {***************************************************************************}
  70. { Internal support routines }
  71. {***************************************************************************}
  72. function ConvertString(const OrigString: String): String;
  73. var
  74. i: Integer;
  75. ConvResult: String;
  76. begin
  77. if GraphStringTransTable = nil then
  78. ConvertString := OrigString
  79. else
  80. begin
  81. SetLength(ConvResult, Length(OrigString));
  82. for i := 1 to Length(OrigString) do
  83. ConvResult[i] := GraphStringTransTable^[OrigString[i]];
  84. ConvertString := ConvResult;
  85. end;
  86. end;
  87. function testfont(p : pchar) : boolean;
  88. begin
  89. testfont:=(p[0]='P') and
  90. (p[1]='K') and
  91. (p[2]=#8) and
  92. (p[3]=#8);
  93. end;
  94. function InstallUserFont(const FontFileName : string) : smallint;
  95. begin
  96. _graphresult:=grOk;
  97. { first check if we do not allocate too many fonts! }
  98. if installedfonts=maxfonts then
  99. begin
  100. _graphresult:=grError;
  101. InstallUserFont := DefaultFont;
  102. exit;
  103. end;
  104. inc(installedfonts);
  105. fonts[installedfonts].name:=FontFileName;
  106. fonts[installedfonts].instr := nil;
  107. fonts[installedfonts].instrlength := 0;
  108. InstallUserFont:=installedfonts;
  109. end;
  110. function Decode(byte1,byte2: char; var x,y: smallint): smallint;
  111. { This routines decoes a signle word in a font opcode section }
  112. { to a stroke record. }
  113. var
  114. b1,b2: shortint;
  115. Begin
  116. b1:=shortint(byte1);
  117. b2:=shortint(byte2);
  118. { Decode the CHR OPCODE }
  119. Decode:=smallint(((b1 and $80) shr 6)+((b2 and $80) shr 7));
  120. { Now get the X,Y coordinates }
  121. { bit 0..7 only which are considered }
  122. { signed values. }
  123. { disable range check mode }
  124. {$ifopt R+}
  125. {$define OPT_R_WAS_ON}
  126. {$R-}
  127. {$endif}
  128. b1:=b1 and $7f;
  129. b2:=b2 and $7f;
  130. { Now if the MSB of these values are set }
  131. { then the value is signed, therefore we }
  132. { sign extend it... }
  133. if (b1 and $40)<>0 then b1:=b1 or $80;
  134. if (b2 and $40)<>0 then b2:=b2 or $80;
  135. x:=smallint(b1);
  136. y:=smallint(b2);
  137. { restore previous range check mode }
  138. {$ifdef OPT_R_WAS_ON}
  139. {$R+}
  140. {$endif}
  141. end;
  142. function unpack(buf: pchar; index: smallint; var Stroke: TStrokes): smallint;
  143. var
  144. po: TStrokes;
  145. num_ops: smallint;
  146. opcode, i, opc: word;
  147. counter: smallint;
  148. lindex: smallint;
  149. jx, jy: smallint;
  150. begin
  151. num_ops := 0;
  152. counter := index;
  153. lindex :=0;
  154. while TRUE do {* For each byte in buffer *}
  155. Begin
  156. Inc(num_ops); {* Count the operation *}
  157. opcode := decode( buf[counter], buf[counter+1] ,jx, jy );
  158. Inc(counter,2);
  159. if( opcode = ord(_END_OF_CHAR) ) then break; {* Exit loop at end of char *}
  160. end;
  161. counter:=index;
  162. for i:=0 to num_ops-1 do { /* For each opcode in buffer */ }
  163. Begin
  164. opc := decode(buf[counter], buf[counter+1], po[lindex].x, po[lindex].y); {* Decode the data field *}
  165. inc(counter,2);
  166. po[lindex].opcode := opc; {* Save the opcode *}
  167. Inc(lindex);
  168. end;
  169. Stroke:=po;
  170. unpack := num_ops; {* return OPS count *}
  171. end;
  172. procedure GetTextPosition(var xpos,ypos: longint; const TextString: string);
  173. begin
  174. if CurrentTextInfo.Font = DefaultFont then
  175. begin
  176. if Currenttextinfo.direction=horizdir then
  177. begin
  178. case Currenttextinfo.horiz of
  179. centertext : XPos:=(textwidth(textstring) shr 1);
  180. lefttext : XPos:=0;
  181. righttext : XPos:=textwidth(textstring);
  182. end;
  183. case Currenttextinfo.vert of
  184. centertext : YPos:=-(textheight(textstring) shr 1);
  185. bottomtext : YPos:=-textheight(textstring);
  186. toptext : YPos:=0;
  187. end;
  188. end else
  189. begin
  190. case Currenttextinfo.horiz of
  191. centertext : XPos:=(textheight(textstring) shr 1);
  192. lefttext : XPos:=textheight(textstring);
  193. righttext : XPos:=textheight(textstring);
  194. end;
  195. case Currenttextinfo.vert of
  196. centertext : YPos:=(textwidth(textstring) shr 1);
  197. bottomtext : YPos:=0;
  198. toptext : YPos:=textwidth(textstring);
  199. end;
  200. end;
  201. end
  202. else
  203. begin
  204. if Currenttextinfo.direction=horizdir then
  205. begin
  206. case CurrentTextInfo.horiz of
  207. centertext : XPos:=(textwidth(textstring) shr 1);
  208. lefttext : XPos:=0;
  209. righttext : XPos:=textwidth(textstring);
  210. end;
  211. case CurrentTextInfo.vert of
  212. centertext : YPos:=(textheight(textstring) shr 1);
  213. bottomtext : YPos:=0;
  214. toptext : YPos:=textheight(textstring);
  215. end;
  216. end else
  217. begin
  218. case CurrentTextInfo.horiz of
  219. centertext : XPos:=(textheight(textstring) shr 1);
  220. lefttext : XPos:=0;
  221. righttext : XPos:=textheight(textstring);
  222. end;
  223. case CurrentTextInfo.vert of
  224. centertext : YPos:=(textwidth(textstring) shr 1);
  225. bottomtext : YPos:=0;
  226. toptext : YPos:=textwidth(textstring);
  227. end;
  228. end;
  229. end;
  230. end;
  231. {***************************************************************************}
  232. { Exported routines }
  233. {***************************************************************************}
  234. function RegisterBGIfont(font : pointer) : smallint;
  235. var
  236. hp : pchar;
  237. b : word;
  238. i: longint;
  239. Header: THeader;
  240. counter: longint;
  241. FontData: pchar;
  242. FHeader: TFHeader;
  243. begin
  244. RegisterBGIfont:=grInvalidFontNum;
  245. i:=0;
  246. { Check if the font header is valid first of all }
  247. if testfont(font) then
  248. begin
  249. hp:=pchar(font);
  250. { Move to EOF in prefix header }
  251. while (hp[i] <> chr($1a)) do Inc(i);
  252. move(hp[i+1],FHeader,sizeof(FHeader));
  253. move(hp[Prefix_Size],header,sizeof(Header));
  254. { check if the font name is already allocated? }
  255. i:=Prefix_Size+sizeof(Header);
  256. for b:=1 to installedfonts do
  257. begin
  258. if fonts[b].name=FHeader.Font_name then
  259. begin
  260. move(FHeader,fonts[b].PHeader,sizeof(FHeader));
  261. move(Header,fonts[b].Header,sizeof(Header));
  262. move(hp[i],Fonts[b].Offsets[Fonts[b].Header.First_Char],Fonts[b].Header.Nr_chars*sizeof(smallint));
  263. Inc(i,Fonts[b].Header.Nr_chars*sizeof(smallint));
  264. move(hp[i],Fonts[b].Widths[Fonts[b].Header.First_Char],Fonts[b].Header.Nr_chars*sizeof(byte));
  265. Inc(i,Fonts[b].Header.Nr_chars*sizeof(byte));
  266. counter:=Fonts[b].PHeader.font_size+PREFIX_SIZE-i;
  267. { allocate also space for null }
  268. GetMem(FontData,Counter+1);
  269. move(hp[i],FontData^,Counter);
  270. { Null terminate the string }
  271. FontData[counter+1] := #0;
  272. if fonts[b].header.Signature<> SIGNATURE then
  273. begin
  274. _graphResult:=grInvalidFont;
  275. Freemem(FontData, Counter+1);
  276. exit;
  277. end;
  278. fonts[b].instr:=FontData;
  279. fonts[b].instrlength:=Counter+1;
  280. RegisterBGIfont:=b;
  281. end;
  282. end;
  283. end
  284. else
  285. RegisterBGIFont:=grInvalidFont;
  286. end;
  287. procedure GetTextSettings(var TextInfo : TextSettingsType);
  288. begin
  289. textinfo:=currenttextinfo;
  290. end;
  291. function TextHeight(const TextString : string) : word;
  292. begin
  293. if Currenttextinfo.font=DefaultFont
  294. then TextHeight:=8*CurrentTextInfo.CharSize
  295. else
  296. TextHeight:=Trunc((fonts[Currenttextinfo.font].header.org_to_cap-
  297. fonts[Currenttextinfo.font].header.org_to_dec) * CurrentYRatio);
  298. end;
  299. function TextWidth(const TextString : string) : word;
  300. var i,x : smallint;
  301. c : byte;
  302. s : String;
  303. begin
  304. x := 0;
  305. { if this is the default font ... }
  306. if Currenttextinfo.font = Defaultfont then
  307. TextWidth:=length(TextString)*8*CurrentTextInfo.CharSize
  308. { This is a stroked font ... }
  309. else begin
  310. s := ConvertString(TextString);
  311. for i:=1 to length(s) do
  312. begin
  313. c:=byte(s[i]);
  314. { dec(c,fonts[Currenttextinfo.font].header.first_char);}
  315. if (c-fonts[Currenttextinfo.font].header.first_char>=
  316. fonts[Currenttextinfo.font].header.nr_chars) then
  317. continue;
  318. x:=x+byte(fonts[Currenttextinfo.font].widths[c]);
  319. end;
  320. TextWidth:=round(x * CurrentXRatio) ;
  321. end;
  322. end;
  323. procedure OutTextXYDefault(x,y : smallint;const TextString : string);
  324. type
  325. Tpoint = record
  326. X,Y: smallint;
  327. end;
  328. var
  329. ConvString : String;
  330. i,j,k,c : longint;
  331. xpos,ypos : longint;
  332. counter : longint;
  333. cnt1,cnt2 : smallint;
  334. cnt3,cnt4 : smallint;
  335. charsize : word;
  336. WriteMode : word;
  337. curX2, curY2, xpos2, ypos2, x2, y2: graph_float;
  338. oldvalues : linesettingstype;
  339. fontbitmap : TBitmapChar;
  340. chr : char;
  341. curx2i,cury2i,
  342. xpos2i,ypos2i : longint;
  343. begin
  344. { save current write mode }
  345. WriteMode := CurrentWriteMode;
  346. CurrentWriteMode := NormalPut;
  347. GetTextPosition(xpos,ypos,textstring);
  348. X:=X-XPos; Y:=Y+YPos;
  349. XPos:=X; YPos:=Y;
  350. ConvString := ConvertString(TextString);
  351. CharSize := CurrentTextInfo.Charsize;
  352. if Currenttextinfo.font=DefaultFont then
  353. begin
  354. c:=length(ConvString);
  355. if CurrentTextInfo.direction=HorizDir then
  356. { Horizontal direction }
  357. begin
  358. for i:=0 to c-1 do
  359. begin
  360. xpos:=x+(i*8)*Charsize;
  361. { we copy the character bitmap before accessing it }
  362. { this improves speed on non optimizing compilers }
  363. { since it is one less address calculation. }
  364. Fontbitmap:=TBitmapChar(DefaultFontData[ConvString[i+1]]);
  365. { no scaling }
  366. if CharSize = 1 then
  367. Begin
  368. for j:=0 to 7 do
  369. for k:=0 to 7 do
  370. if Fontbitmap[j,k]<>0 then
  371. PutPixel(xpos+k,j+y,CurrentColor)
  372. else if DrawTextBackground then
  373. PutPixel(xpos+k,j+y,CurrentBkColor);
  374. end
  375. else
  376. { perform scaling of bitmap font }
  377. Begin
  378. j:=0;
  379. cnt3:=0;
  380. while j <= 7 do
  381. begin
  382. { X-axis scaling }
  383. for cnt4 := 0 to charsize-1 do
  384. begin
  385. k:=0;
  386. cnt2 := 0;
  387. while k <= 7 do
  388. begin
  389. for cnt1 := 0 to charsize-1 do
  390. begin
  391. If FontBitmap[j,k] <> 0 then
  392. PutPixel(xpos+cnt1+cnt2,y+cnt3+cnt4,CurrentColor)
  393. else if DrawTextBackground then
  394. PutPixel(xpos+cnt1+cnt2,y+cnt3+cnt4,CurrentBkColor);
  395. end;
  396. Inc(k);
  397. Inc(cnt2,charsize);
  398. end;
  399. end;
  400. Inc(j);
  401. Inc(cnt3,charsize);
  402. end;
  403. end;
  404. end;
  405. end
  406. else
  407. { Vertical direction }
  408. begin
  409. for i:=0 to c-1 do
  410. begin
  411. chr := ConvString[i+1];
  412. Fontbitmap:=TBitmapChar(DefaultFontData[chr]);
  413. ypos := y-(i shl 3)*CharSize;
  414. { no scaling }
  415. if CharSize = 1 then
  416. Begin
  417. for j:=0 to 7 do
  418. for k:=0 to 7 do
  419. if Fontbitmap[j,k] <> 0 then
  420. PutPixel(xpos+j,ypos-k,CurrentColor)
  421. else if DrawTextBackground then
  422. PutPixel(xpos+j,ypos-k,CurrentBkColor);
  423. end
  424. else
  425. { perform scaling of bitmap font }
  426. Begin
  427. j:=0;
  428. cnt3:=0;
  429. while j<=7 do
  430. begin
  431. { X-axis scaling }
  432. for cnt4 := 0 to charsize-1 do
  433. begin
  434. k:=0;
  435. cnt2 := 0;
  436. while k<=7 do
  437. begin
  438. for cnt1 := 0 to charsize-1 do
  439. begin
  440. If FontBitmap[j,k] <> 0 then
  441. PutPixel(xpos+cnt3-cnt4,ypos+cnt1-cnt2,CurrentColor)
  442. else if DrawTextBackground then
  443. PutPixel(xpos+cnt3-cnt4,ypos+cnt1-cnt2,CurrentBkColor);
  444. end;
  445. Inc(k);
  446. Inc(cnt2,charsize);
  447. end;
  448. end;
  449. Inc(j);
  450. Inc(cnt3,charsize);
  451. end;
  452. end;
  453. end;
  454. end;
  455. end else
  456. { This is a stroked font which is already loaded into memory }
  457. begin
  458. getlinesettings(oldvalues);
  459. { reset line style to defaults }
  460. setlinestyle(solidln,oldvalues.pattern,normwidth);
  461. if Currenttextinfo.direction=vertdir then
  462. xpos:=xpos + Textheight(ConvString);
  463. CurX2:=xpos; xpos2 := curX2; x2 := xpos2;
  464. CurY2:=ypos; ypos2 := curY2; y2 := ypos2;
  465. { x:=xpos; y:=ypos;}
  466. for i:=1 to length(ConvString) do
  467. begin
  468. c:=byte(ConvString[i]);
  469. { Stroke_Count[c] := }
  470. unpack( fonts[CurrentTextInfo.font].instr,
  471. fonts[CurrentTextInfo.font].Offsets[c], Strokes );
  472. counter:=0;
  473. while true do
  474. begin
  475. if CurrentTextInfo.direction=VertDir then
  476. begin
  477. xpos2:=x2-(Strokes[counter].Y*CurrentYRatio);
  478. ypos2:=y2-(Strokes[counter].X*CurrentXRatio);
  479. end
  480. else
  481. begin
  482. xpos2:=x2+(Strokes[counter].X*CurrentXRatio) ;
  483. ypos2:=y2-(Strokes[counter].Y*CurrentYRatio) ;
  484. end;
  485. case opcodes(Strokes[counter].opcode) of
  486. _END_OF_CHAR: break;
  487. _DO_SCAN: begin
  488. { Currently unsupported };
  489. end;
  490. _MOVE : Begin
  491. CurX2 := XPos2;
  492. CurY2 := YPos2;
  493. end;
  494. _DRAW: Begin
  495. curx2i:=trunc(CurX2);
  496. cury2i:=trunc(CurY2);
  497. xpos2i:=trunc(xpos2);
  498. ypos2i:=trunc(ypos2);
  499. { this optimization doesn't matter that much
  500. if (curx2i=xpos2i) then
  501. begin
  502. if (cury2i=ypos2i) then
  503. putpixel(curx2i,cury2i,currentcolor)
  504. else if (cury2i+1=ypos2i) or
  505. (cury2i=ypos2i+1) then
  506. begin
  507. putpixel(curx2i,cury2i,currentcolor);
  508. putpixel(curx2i,ypos2i,currentcolor);
  509. end
  510. else
  511. Line(curx2i,cury2i,xpos2i,ypos2i);
  512. end
  513. else if (cury2i=ypos2i) then
  514. begin
  515. if (curx2i+1=xpos2i) or
  516. (curx2i=xpos2i+1) then
  517. begin
  518. putpixel(curx2i,cury2i,currentcolor);
  519. putpixel(xpos2i,cury2i,currentcolor);
  520. end
  521. else
  522. Line(curx2i,cury2i,xpos2i,ypos2i);
  523. end
  524. else
  525. }
  526. Line(curx2i,cury2i,xpos2i,ypos2i);
  527. CurX2:=xpos2;
  528. CurY2:=ypos2;
  529. end;
  530. else
  531. Begin
  532. end;
  533. end;
  534. Inc(counter);
  535. end; { end while }
  536. if Currenttextinfo.direction=VertDir then
  537. y2:=y2-(byte(fonts[CurrenttextInfo.font].widths[c])*CurrentXRatio)
  538. else
  539. x2:=x2+(byte(fonts[Currenttextinfo.font].widths[c])*CurrentXRatio);
  540. end;
  541. setlinestyle( oldvalues.linestyle, oldvalues.pattern, oldvalues.thickness);
  542. end;
  543. { restore write mode }
  544. CurrentWriteMode := WriteMode;
  545. end;
  546. procedure OutText(const TextString : string);
  547. var x,y:smallint;
  548. begin
  549. { Save CP }
  550. x:=CurrentX;
  551. y:=CurrentY;
  552. OutTextXY(CurrentX,CurrentY,TextString);
  553. { If the direction is Horizontal and the justification left }
  554. { then and only then do we update the CP }
  555. if (Currenttextinfo.direction=HorizDir) and
  556. (Currenttextinfo.horiz=LeftText) then
  557. inc(x,textwidth(TextString));
  558. { Update the CP }
  559. CurrentX := X;
  560. CurrentY := Y;
  561. end;
  562. procedure SetTextJustify(horiz,vert : word);
  563. begin
  564. if (horiz<0) or (horiz>2) or
  565. (vert<0) or (vert>2) then
  566. begin
  567. _graphresult:=grError;
  568. exit;
  569. end;
  570. Currenttextinfo.horiz:=horiz;
  571. Currenttextinfo.vert:=vert;
  572. end;
  573. procedure SetTextStyle(font,direction : word;charsize : word);
  574. var
  575. f : file;
  576. Prefix: array[0..Prefix_Size-1] of char; {* File Prefix Holder *}
  577. Length, Current: longint;
  578. FontData: Pchar;
  579. hp : pchar;
  580. i : longint;
  581. begin
  582. if font>installedfonts then
  583. begin
  584. _graphresult:=grInvalidFontNum;
  585. exit;
  586. end;
  587. Currenttextinfo.font:=font;
  588. if (direction<>HorizDir) and (direction<>VertDir) then
  589. direction:=HorizDir;
  590. Currenttextinfo.direction:=direction;
  591. { According to the Turbo Pascal programmer's reference }
  592. { maximum charsize for bitmapped font is 10 }
  593. if (CurrentTextInfo.Font = DefaultFont) and (Charsize > 10) then
  594. Currenttextinfo.charsize:=10
  595. else if charsize<1 then
  596. Currenttextinfo.charsize:=1
  597. else
  598. Currenttextinfo.charsize:=charsize;
  599. { This is only valid for stroked fonts }
  600. {$ifdef logging}
  601. LogLn('(org_to_cap - org_to_dec): ' + strf(
  602. fonts[Currenttextinfo.font].header.org_to_cap-
  603. fonts[Currenttextinfo.font].header.org_to_dec));
  604. {$endif logging}
  605. if (charsize <> usercharsize) then
  606. Case CharSize of
  607. 1: Begin
  608. CurrentXRatio := 0.55;
  609. CurrentYRatio := 0.55;
  610. End;
  611. 2: Begin
  612. CurrentXRatio := 0.65;
  613. CurrentYRatio := 0.65;
  614. End;
  615. 3: Begin
  616. CurrentXRatio := 0.75;
  617. CurrentYRatio := 0.75;
  618. End;
  619. 4: Begin
  620. CurrentXRatio := 1.0;
  621. CurrentYRatio := 1.0;
  622. End;
  623. 5: Begin
  624. CurrentXRatio := 1.3;
  625. CurrentYRatio := 1.3;
  626. End;
  627. 6: Begin
  628. CurrentXRatio := 1.65;
  629. CurrentYRatio := 1.65
  630. End;
  631. 7: Begin
  632. CurrentXRatio := 2.0;
  633. CurrentYRatio := 2.0;
  634. End;
  635. 8: Begin
  636. CurrentXRatio := 2.5;
  637. CurrentYRatio := 2.5;
  638. End;
  639. 9: Begin
  640. CurrentXRatio := 3.0;
  641. CurrentYRatio := 3.0;
  642. End;
  643. 10: Begin
  644. CurrentXRatio := 4.0;
  645. CurrentYRatio := 4.0;
  646. End
  647. End;
  648. { if this is a stroked font then load it if not already loaded }
  649. { into memory... }
  650. if (font>DefaultFont) and not assigned(fonts[font].instr) then
  651. begin
  652. assign(f,bgipath+fonts[font].name+'.CHR');
  653. {$ifopt I+}
  654. {$define IOCHECK_WAS_ON}
  655. {$i-}
  656. {$endif}
  657. reset(f,1);
  658. {$ifdef IOCHECK_WAS_ON}
  659. {$i+}
  660. {$endif}
  661. if ioresult<>0 then
  662. begin
  663. _graphresult:=grFontNotFound;
  664. Currenttextinfo.font:=DefaultFont;
  665. exit;
  666. end;
  667. {* Read in the file prefix *}
  668. BlockRead(F, Prefix, Prefix_Size);
  669. hp:=Prefix;
  670. i:=0;
  671. while (hp[i] <> chr($1a)) do Inc(i);
  672. move(hp[i+1],fonts[font].PHeader,sizeof(TFHeader));
  673. (* Read in the Header file *)
  674. BlockRead(F,fonts[font].Header,Sizeof(THeader));
  675. BlockRead(F,Fonts[font].Offsets[Fonts[font].Header.First_Char],Fonts[font].Header.Nr_chars*sizeof(smallint));
  676. {* Load the character width table into memory. *}
  677. BlockRead(F,Fonts[font].Widths[Fonts[font].Header.First_Char],Fonts[font].Header.Nr_chars*sizeof(byte));
  678. {* Determine the length of the stroke database. *}
  679. current := FilePos( f ); {* Current file location *}
  680. Seek( f, FileSize(F)); {* Go to the end of the file *}
  681. length := FilePos( f ); {* Get the file length *}
  682. Seek( f, current); {* Restore old file location *}
  683. {* Load the stroke database. *}
  684. { also allocate space for Null character }
  685. Getmem(FontData, Length+1); {* Create space for font data *}
  686. BlockRead(F, FontData^, length-current); {* Load the stroke data *}
  687. FontData[length-current+1] := #0;
  688. if fonts[font].header.Signature<> SIGNATURE then
  689. begin
  690. _graphResult:=grInvalidFont;
  691. Currenttextinfo.font:=DefaultFont;
  692. Freemem(FontData, Length+1);
  693. exit;
  694. end;
  695. fonts[font].instr:=FontData;
  696. fonts[font].instrLength:=Length+1;
  697. if not testfont(Prefix) then
  698. begin
  699. _graphresult:=grInvalidFont;
  700. Currenttextinfo.font:=DefaultFont;
  701. Freemem(FontData, Length+1);
  702. end;
  703. close(f);
  704. end;
  705. end;
  706. procedure SetUserCharSize(Multx,Divx,Multy,Divy : word);
  707. begin
  708. CurrentXRatio := MultX / DivX;
  709. CurrentYRatio := MultY / DivY;
  710. end;
  711. {
  712. $Log$
  713. Revision 1.5 2002-09-07 15:07:47 peter
  714. * old logs removed and tabs fixed
  715. Revision 1.4 2002/09/07 12:36:15 carl
  716. - unit cleanup (removed unused defines)
  717. * compilation options are restored
  718. Revision 1.3 2002/07/18 07:11:11 pierre
  719. merged from FIXES branch: DrawTextBackground support
  720. }