gtext.inc 29 KB

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