text.ppi 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 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. { Textausgabe }
  13. {***************************************************************************}
  14. const
  15. { maximal 16 Vektorfonts unterst�tzen }
  16. { um mehr Fonts laden zu k”nnen, muá }
  17. { diese Variable erh”ht werden }
  18. maxfonts = 16;
  19. fontdivs:array[0..maxfonts]of integer=
  20. (1,4,3,4,4,4,4,4,4,3,3,1,1,1,1,1,1);
  21. type
  22. pbyte = ^byte;
  23. {$PACKRECORDS 1}
  24. pfontdata = ^tfontdata;
  25. tfontdata = record
  26. filetyp : char;
  27. nr_chars : word;
  28. undefined1 : byte;
  29. value_first_char : byte;
  30. undefined2 : array[1..3] of byte;
  31. dist_origin_top : shortint;
  32. dist_origin_baseline : shortint;
  33. dist_origin_bottom : shortint;
  34. undefined3 : array[1..5] of byte;
  35. end;
  36. {$PACKRECORDS NORMAL}
  37. tfontrec = record
  38. name : string[8];
  39. data : pointer;
  40. header : pfontdata;
  41. offsets : pword;
  42. widths : pbyte;
  43. instr : pbyte;
  44. end;
  45. var
  46. fonts : array[1..maxfonts] of tfontrec;
  47. installedfonts : longint;
  48. {$I FONT.PPI}
  49. { gibt true zur�ck, wenn p auf eine g�ltige Fontdatei zeigt }
  50. function testfont(p : pointer) : boolean;
  51. begin
  52. testfont:=(pchar(p)^='P') and
  53. (pchar(p+1)^='K') and
  54. (pchar(p+2)^=#8) and
  55. (pchar(p+3)^=#8);
  56. end;
  57. { setzt die Hilfsdaten f�r den Font mit der Nr. font }
  58. { der Zeiger data muá schon gesetzt sein }
  59. function setupfont(font : word) : integer;
  60. begin
  61. setupfont:=grOK;
  62. fonts[font].header:=fonts[font].data+$80;
  63. if fonts[font].header^.filetyp<>'+' then
  64. begin
  65. setupfont:=grInvalidFont;
  66. exit;
  67. end;
  68. fonts[font].offsets:=fonts[font].data+$90;
  69. fonts[font].widths:=pbyte(fonts[font].offsets+fonts[font].header^.nr_chars*2);
  70. fonts[font].instr:=fonts[font].widths+fonts[font].header^.nr_chars;
  71. end;
  72. function InstallUserFont(const FontFileName : string) : integer;
  73. begin
  74. _graphresult:=grOk;
  75. { es muá kein Graphikmodus gesetzt sein! }
  76. { ist noch Platz f�r einen Font ? }
  77. if installedfonts=maxfonts then
  78. begin
  79. _graphresult:=grError;
  80. exit;
  81. end;
  82. inc(installedfonts);
  83. fonts[installedfonts].name:=FontFileName;
  84. fonts[installedfonts].data:=nil;
  85. InstallUserFont:=installedfonts;
  86. end;
  87. function RegisterBGIfont(font : pointer) : integer;
  88. var
  89. hp : pbyte;
  90. b : word;
  91. name : string[12];
  92. begin
  93. { noch nicht garantiert, daá alles klappt }
  94. RegisterBGIfont:=grInvalidFontNum;
  95. { es muá kein Graphikmodus gesetzt sein! }
  96. if testfont(font) then
  97. begin
  98. hp:=pbyte(font);
  99. { Ende des Textheaders suchen }
  100. while hp^<>$1a do
  101. hp:=hp+1;
  102. { auf Start des Names springen }
  103. hp:=hp+3;
  104. { Namen lesen }
  105. name:='';
  106. for b:=0 to 3 do
  107. name:=name+char((hp+b)^);
  108. { richtigen Font suchen }
  109. for b:=1 to installedfonts do
  110. begin
  111. if fonts[b].name=name then
  112. begin
  113. fonts[b].data:=font;
  114. RegisterBGIfont:=grOK;
  115. RegisterBGIfont:=setupfont(b);
  116. end;
  117. end;
  118. end
  119. else
  120. RegisterBGIFont:=grInvalidFont;
  121. end;
  122. procedure GetTextSettings(var TextInfo : TextSettingsType);
  123. begin
  124. _graphresult:=grOk;
  125. if not isgraphmode then
  126. begin
  127. _graphresult:=grnoinitgraph;
  128. exit;
  129. end;
  130. textinfo:=akttextinfo;
  131. end;
  132. procedure OutText(const TextString : string);
  133. var x,y:integer;
  134. begin
  135. _graphresult:=grOk;
  136. if not isgraphmode then
  137. begin
  138. _graphresult:=grnoinitgraph;
  139. exit;
  140. end;
  141. x:=curx; y:=cury;
  142. OutTextXY(curx,cury,TextString);
  143. { wenn horizontal und linksb�ndig ausgegeben wird, dann }
  144. { Grafikcursor nachf�hren }
  145. if (akttextinfo.direction=HorizDir) and
  146. (akttextinfo.horiz=LeftText) then
  147. inc(x,textwidth(TextString));
  148. curx:=x; cury:=y; { LineTo manipuliert den GrafikCursor !! }
  149. end;
  150. procedure outtext(const charakter : char);
  151. var s:string;
  152. x,y:integer;
  153. begin
  154. s:=charakter;
  155. _graphresult:=grOk;
  156. if not isgraphmode then
  157. begin
  158. _graphresult:=grnoinitgraph;
  159. exit;
  160. end;
  161. x:=curx; y:=cury;
  162. OutTextXY(curx,cury,s);
  163. { wenn horizontal und linksb�ndig ausgegeben wird, dann }
  164. { Grafikcursor nachf�hren }
  165. { if (akttextinfo.direction=HorizDir) and
  166. (akttextinfo.horiz=LeftText) then }
  167. inc(x,textwidth(s));
  168. curx:=x; cury:=y; { LineTo manipuliert den GrafikCursor !! }
  169. end;
  170. procedure OutTextXY(x,y : integer;const TextString : string);
  171. var
  172. b1,b2 : shortint;
  173. c,instr,mask : byte;
  174. i,j,k : longint;
  175. oldvalues : linesettingstype;
  176. nextpos : word;
  177. xpos,ypos,offs: longint;
  178. FontPtr : Pointer;
  179. begin
  180. _graphresult:=grOk;
  181. if not isgraphmode then
  182. begin
  183. _graphresult:=grnoinitgraph;
  184. exit;
  185. end;
  186. { wirkliche x- und y-Startposition berechnen }
  187. if akttextinfo.direction=horizdir then
  188. begin
  189. case akttextinfo.horiz of
  190. centertext : XPos:=(textwidth(textstring) shr 1);
  191. lefttext : XPos:=0;
  192. righttext : XPos:=textwidth(textstring);
  193. end;
  194. case akttextinfo.vert of
  195. centertext : YPos:=(textheight(textstring) shr 1);
  196. bottomtext : YPos:=0;
  197. toptext : YPos:=textheight(textstring);
  198. end;
  199. end else
  200. begin
  201. case akttextinfo.horiz of
  202. centertext : XPos:=(textheight(textstring) shr 1);
  203. lefttext : XPos:=0;
  204. righttext : XPos:=textheight(textstring);
  205. end;
  206. case akttextinfo.vert of
  207. centertext : YPos:=(textwidth(textstring) shr 1);
  208. bottomtext : YPos:=0;
  209. toptext : YPos:=textwidth(textstring);
  210. end;
  211. end;
  212. X:=X-XPos; Y:=Y+YPos;
  213. XPos:=X; YPos:=Y;
  214. if akttextinfo.font=DefaultFont then begin
  215. y:=y-6;
  216. c:=textwidth(textstring) div 8 - 1; { Charcounter }
  217. FontPtr:=@defaultfontdata;
  218. for i:=0 to c do begin
  219. offs:=ord(textString[i+1]) shl 3; { Offset des Chars in Data }
  220. for j:=0 to 7 do begin
  221. mask:=$80;
  222. b1:=defaultfontdata[offs+j]; { Offset der Charzeile }
  223. xpos:=i shl 3+x;
  224. for k:=0 to 7 do begin
  225. if (b1 and mask) <> 0 then putpixel(xpos+k,j+y,aktcolor);
  226. mask:=mask shr 1;
  227. end;
  228. end;
  229. end;
  230. end else
  231. begin
  232. { Linienstil setzen }
  233. getlinesettings(oldvalues);
  234. setlinestyle(solidln,oldvalues.pattern,normwidth);
  235. if akttextinfo.direction=vertdir then xpos:=xpos + Textheight(textstring);
  236. curx:=xpos; cury:=ypos; x:=xpos; y:=ypos;
  237. for i:=1 to length(textstring) do
  238. begin
  239. c:=byte(textstring[i]);
  240. c:=c-fonts[akttextinfo.font].header^.value_first_char;
  241. { definiertes Zeichen ? }
  242. if (c<0) or (c>=fonts[akttextinfo.font].header^.nr_chars) then continue;
  243. nextpos:=fonts[akttextinfo.font].offsets[c];
  244. while true do
  245. begin
  246. b1:=fonts[akttextinfo.font].instr[nextpos];
  247. nextpos:=nextpos+1;
  248. b2:=fonts[akttextinfo.font].instr[nextpos];
  249. nextpos:=nextpos+1;
  250. instr:=((b1 and $80) shr 6)+((b2 and $80) shr 7);
  251. b1:=b1 and $7f;
  252. b2:=b2 and $7f;
  253. { Vorzeichen erweitern }
  254. if (b1 and $40)<>0 then b1:=b1 or $80;
  255. if (b2 and $40)<>0 then b2:=b2 or $80;
  256. { neue Stiftposition berechnen und skalieren }
  257. if akttextinfo.direction=VertDir then
  258. begin
  259. xpos:=x-((b2*aktmultx) div aktdivx);
  260. ypos:=y-((b1*aktmulty) div aktdivy);
  261. end
  262. else
  263. begin
  264. xpos:=x+((b1*aktmultx) div aktdivx) ;
  265. ypos:=y-((b2*aktmulty) div aktdivy) ;
  266. end;
  267. case instr of
  268. 0 : break;
  269. 2 : begin curx:=xpos; cury:=ypos; end;
  270. 3 : begin line(curx,cury,xpos,ypos);
  271. curx:=xpos; cury:=ypos;
  272. end;
  273. end;
  274. end;
  275. if akttextinfo.direction=VertDir then
  276. y:=y-(fonts[akttextinfo.font].widths[c]*aktmultx div aktdivx)
  277. else
  278. x:=x+(fonts[akttextinfo.font].widths[c]*aktmultx div aktdivx) ;
  279. end;
  280. setlinestyle( oldvalues.linestyle, oldvalues.pattern, oldvalues.thickness);
  281. end;
  282. end;
  283. procedure outtextxy(x,y: Integer;const charakter : char);
  284. var s:string;
  285. begin
  286. s:=charakter;
  287. outtextXY(x,y,s);
  288. end;
  289. function TextHeight(const TextString : string) : word;
  290. begin
  291. _graphresult:=grOk;
  292. if not isgraphmode then
  293. begin
  294. _graphresult:=grnoinitgraph;
  295. exit;
  296. end;
  297. if akttextinfo.font=DefaultFont
  298. then TextHeight:=6+akttextinfo.charsize
  299. else
  300. TextHeight:=(((fonts[akttextinfo.font].header^.dist_origin_top-
  301. fonts[akttextinfo.font].header^.dist_origin_bottom) * aktmulty) div aktdivy) ;
  302. end;
  303. function TextWidth(const TextString : string) : word;
  304. var i,x : Integer;
  305. c : byte;
  306. begin
  307. _graphresult:=grOk; x:=0;
  308. if not isgraphmode then
  309. begin
  310. _graphresult:=grnoinitgraph;
  311. exit;
  312. end;
  313. if akttextinfo.font = Defaultfont then
  314. TextWidth:=length(TextString)*8*akttextinfo.charsize
  315. else begin
  316. for i:=1 to length(TextString) do begin
  317. c:=byte(textstring[i]);
  318. dec(c,fonts[akttextinfo.font].header^.value_first_char);
  319. { definiertes Zeichen ? }
  320. if (c<0) or (c>=fonts[akttextinfo.font].header^.nr_chars) then
  321. continue;
  322. x:=x+fonts[akttextinfo.font].widths[c];
  323. end;
  324. TextWidth:=((x * aktmultx) div aktdivx) ;
  325. end;
  326. end;
  327. procedure SetTextJustify(horiz,vert : word);
  328. begin
  329. _graphresult:=grOk;
  330. if not isgraphmode then
  331. begin
  332. _graphresult:=grnoinitgraph;
  333. exit;
  334. end;
  335. if (horiz<0) or (horiz>2) or
  336. (vert<0) or (vert>2) then
  337. begin
  338. _graphresult:=grError;
  339. exit;
  340. end;
  341. akttextinfo.horiz:=horiz;
  342. akttextinfo.vert:=vert;
  343. end;
  344. procedure SetTextStyle(font,direction : word;charsize : word);
  345. var
  346. f : file;
  347. begin
  348. _graphresult:=grOk;
  349. if not isgraphmode then
  350. begin
  351. _graphresult:=grnoinitgraph;
  352. exit;
  353. end;
  354. { Parameter auf G�ltigkeit �berpr�fen }
  355. if font>installedfonts then
  356. begin
  357. _graphresult:=grInvalidFontNum;
  358. exit;
  359. end;
  360. akttextinfo.font:=font;
  361. if (direction<>HorizDir) and (direction<>VertDir) then
  362. direction:=HorizDir;
  363. akttextinfo.direction:=direction;
  364. akttextinfo.charsize:=charsize;
  365. if (charsize <> usercharsize) then begin
  366. aktmultx:=charsize;
  367. aktdivx:=fontdivs[font];
  368. aktmulty:=charsize;
  369. aktdivy:=fontdivs[font];
  370. end;
  371. { Fontdatei laden ? }
  372. if (font>0) and not assigned(fonts[font].data) then
  373. begin
  374. assign(f,bgipath+fonts[font].name+'.CHR');
  375. reset(f,1);
  376. if ioresult<>0 then
  377. begin
  378. _graphresult:=grFontNotFound;
  379. akttextinfo.font:=DefaultFont;
  380. exit;
  381. end;
  382. getmem(fonts[font].data,filesize(f));
  383. if not assigned(fonts[font].data) then
  384. begin
  385. _graphresult:=grNoFontMem;
  386. akttextinfo.font:=DefaultFont;
  387. exit;
  388. end;
  389. blockread(f,fonts[font].data^,filesize(f));
  390. if testfont(fonts[font].data) then
  391. _graphresult:=setupfont(font)
  392. else
  393. begin
  394. _graphresult:=grInvalidFont;
  395. akttextinfo.font:=DefaultFont;
  396. freemem(fonts[font].data,filesize(f));
  397. end;
  398. close(f);
  399. end;
  400. end;
  401. procedure SetUserCharSize(Multx,Divx,Multy,Divy : word);
  402. begin
  403. _graphresult:=grOk;
  404. if not isgraphmode then
  405. begin
  406. _graphresult:=grnoinitgraph;
  407. exit;
  408. end;
  409. aktmultx:=Multx;
  410. aktdivx:=Divx;
  411. aktmulty:=Multy;
  412. aktdivy:=Divy;
  413. end;
  414. {
  415. $Log$
  416. Revision 1.1 1998-03-25 11:18:42 root
  417. Initial revision
  418. Revision 1.3 1998/01/26 11:58:41 michael
  419. + Added log at the end
  420. Working file: rtl/dos/ppi/text.ppi
  421. description:
  422. ----------------------------
  423. revision 1.2
  424. date: 1997/12/01 12:21:34; author: michael; state: Exp; lines: +14 -0
  425. + added copyright reference in header.
  426. ----------------------------
  427. revision 1.1
  428. date: 1997/11/27 08:33:51; author: michael; state: Exp;
  429. Initial revision
  430. ----------------------------
  431. revision 1.1.1.1
  432. date: 1997/11/27 08:33:51; author: michael; state: Exp; lines: +0 -0
  433. FPC RTL CVS start
  434. =============================================================================
  435. }