text.ppi 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  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,jj,k,l : 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;
  213. Y:=Y+YPos;
  214. XPos:=X; YPos:=Y;
  215. if akttextinfo.font=DefaultFont then begin
  216. if akttextinfo.direction=horizdir then
  217. ypos:=ypos-6*akttextinfo.charsize
  218. {else
  219. xpos:=xpos-6*akttextinfo.charsize};
  220. (* c:=textwidth(textstring) div 8 - 1; { Charcounter }
  221. gave wrong values if charsize<>1 PM *)
  222. c:=length(textstring); { Charcounter }
  223. FontPtr:=@defaultfontdata;
  224. for i:=1 to c do begin
  225. offs:=ord(textString[i]) shl 3; { Offset des Chars in Data }
  226. for j:=0 to 7 do begin
  227. mask:=$80;
  228. b1:=defaultfontdata[offs+j]; { Offset der Charzeile }
  229. jj:=j*akttextinfo.charsize;
  230. if akttextinfo.direction=horizdir then
  231. xpos:=x+((i-1) shl 3)*akttextinfo.charsize
  232. else
  233. ypos:=y-((i-1) shl 3)*akttextinfo.charsize;
  234. for k:=0 to {7}8*akttextinfo.charsize-1 do
  235. begin
  236. if (b1 and mask) <> 0 then
  237. for l:=0 to akttextinfo.charsize-1 do
  238. if akttextinfo.direction=horizdir then
  239. putpixeli(xpos+k,jj+ypos+l,aktcolor)
  240. else
  241. putpixeli(xpos+jj+l,ypos-k,aktcolor)
  242. else if ClearText then
  243. for l:=0 to akttextinfo.charsize-1 do
  244. if akttextinfo.direction=horizdir then
  245. putpixeli(xpos+k,jj+ypos+l,aktbackcolor)
  246. else
  247. putpixeli(xpos+jj+l,ypos-k,aktbackcolor);
  248. if (k mod akttextinfo.charsize) = akttextinfo.charsize-1 then
  249. mask:=mask shr 1;
  250. end;
  251. end;
  252. end;
  253. end else
  254. begin
  255. { Linienstil setzen }
  256. getlinesettings(oldvalues);
  257. setlinestyle(solidln,oldvalues.pattern,normwidth);
  258. if akttextinfo.direction=vertdir then xpos:=xpos + Textheight(textstring);
  259. curx:=xpos; cury:=ypos; x:=xpos; y:=ypos;
  260. for i:=1 to length(textstring) do
  261. begin
  262. c:=byte(textstring[i]);
  263. c:=c-fonts[akttextinfo.font].header^.value_first_char;
  264. { definiertes Zeichen ? }
  265. if (c<0) or (c>=fonts[akttextinfo.font].header^.nr_chars) then continue;
  266. nextpos:=fonts[akttextinfo.font].offsets[c];
  267. while true do
  268. begin
  269. b1:=fonts[akttextinfo.font].instr[nextpos];
  270. nextpos:=nextpos+1;
  271. b2:=fonts[akttextinfo.font].instr[nextpos];
  272. nextpos:=nextpos+1;
  273. instr:=((b1 and $80) shr 6)+((b2 and $80) shr 7);
  274. b1:=b1 and $7f;
  275. b2:=b2 and $7f;
  276. { Vorzeichen erweitern }
  277. if (b1 and $40)<>0 then b1:=b1 or $80;
  278. if (b2 and $40)<>0 then b2:=b2 or $80;
  279. { neue Stiftposition berechnen und skalieren }
  280. if akttextinfo.direction=VertDir then
  281. begin
  282. xpos:=x-((b2*aktmultx) div aktdivx);
  283. ypos:=y-((b1*aktmulty) div aktdivy);
  284. end
  285. else
  286. begin
  287. xpos:=x+((b1*aktmultx) div aktdivx) ;
  288. ypos:=y-((b2*aktmulty) div aktdivy) ;
  289. end;
  290. case instr of
  291. 0 : break;
  292. 2 : begin curx:=xpos; cury:=ypos; end;
  293. 3 : begin line(curx,cury,xpos,ypos);
  294. curx:=xpos; cury:=ypos;
  295. end;
  296. end;
  297. end;
  298. if akttextinfo.direction=VertDir then
  299. y:=y-(fonts[akttextinfo.font].widths[c]*aktmultx div aktdivx)
  300. else
  301. x:=x+(fonts[akttextinfo.font].widths[c]*aktmultx div aktdivx) ;
  302. end;
  303. setlinestyle( oldvalues.linestyle, oldvalues.pattern, oldvalues.thickness);
  304. end;
  305. end;
  306. procedure outtextxy(x,y: Integer;const charakter : char);
  307. var s:string;
  308. begin
  309. s:=charakter;
  310. outtextXY(x,y,s);
  311. end;
  312. function TextHeight(const TextString : string) : word;
  313. begin
  314. _graphresult:=grOk;
  315. if not isgraphmode then
  316. begin
  317. _graphresult:=grnoinitgraph;
  318. exit;
  319. end;
  320. if akttextinfo.font=DefaultFont
  321. then TextHeight:=6+akttextinfo.charsize
  322. else
  323. TextHeight:=(((fonts[akttextinfo.font].header^.dist_origin_top-
  324. fonts[akttextinfo.font].header^.dist_origin_bottom) * aktmulty) div aktdivy) ;
  325. end;
  326. function TextWidth(const TextString : string) : word;
  327. var i,x : Integer;
  328. c : byte;
  329. begin
  330. _graphresult:=grOk; x:=0;
  331. if not isgraphmode then
  332. begin
  333. _graphresult:=grnoinitgraph;
  334. exit;
  335. end;
  336. if akttextinfo.font = Defaultfont then
  337. TextWidth:=length(TextString)*8*akttextinfo.charsize
  338. else begin
  339. for i:=1 to length(TextString) do begin
  340. c:=byte(textstring[i]);
  341. dec(c,fonts[akttextinfo.font].header^.value_first_char);
  342. { definiertes Zeichen ? }
  343. if (c<0) or (c>=fonts[akttextinfo.font].header^.nr_chars) then
  344. continue;
  345. x:=x+fonts[akttextinfo.font].widths[c];
  346. end;
  347. TextWidth:=((x * aktmultx) div aktdivx) ;
  348. end;
  349. end;
  350. procedure SetTextJustify(horiz,vert : word);
  351. begin
  352. _graphresult:=grOk;
  353. if not isgraphmode then
  354. begin
  355. _graphresult:=grnoinitgraph;
  356. exit;
  357. end;
  358. if (horiz<0) or (horiz>2) or
  359. (vert<0) or (vert>2) then
  360. begin
  361. _graphresult:=grError;
  362. exit;
  363. end;
  364. akttextinfo.horiz:=horiz;
  365. akttextinfo.vert:=vert;
  366. end;
  367. procedure SetTextStyle(font,direction : word;charsize : word);
  368. var
  369. f : file;
  370. begin
  371. _graphresult:=grOk;
  372. if not isgraphmode then
  373. begin
  374. _graphresult:=grnoinitgraph;
  375. exit;
  376. end;
  377. { Parameter auf G�ltigkeit �berpr�fen }
  378. if font>installedfonts then
  379. begin
  380. _graphresult:=grInvalidFontNum;
  381. exit;
  382. end;
  383. akttextinfo.font:=font;
  384. if (direction<>HorizDir) and (direction<>VertDir) then
  385. direction:=HorizDir;
  386. akttextinfo.direction:=direction;
  387. akttextinfo.charsize:=charsize;
  388. if (charsize <> usercharsize) then begin
  389. aktmultx:=charsize;
  390. aktdivx:=fontdivs[font];
  391. aktmulty:=charsize;
  392. aktdivy:=fontdivs[font];
  393. end;
  394. { Fontdatei laden ? }
  395. if (font>0) and not assigned(fonts[font].data) then
  396. begin
  397. assign(f,bgipath+fonts[font].name+'.CHR');
  398. reset(f,1);
  399. if ioresult<>0 then
  400. begin
  401. _graphresult:=grFontNotFound;
  402. akttextinfo.font:=DefaultFont;
  403. exit;
  404. end;
  405. getmem(fonts[font].data,filesize(f));
  406. if not assigned(fonts[font].data) then
  407. begin
  408. _graphresult:=grNoFontMem;
  409. akttextinfo.font:=DefaultFont;
  410. exit;
  411. end;
  412. blockread(f,fonts[font].data^,filesize(f));
  413. if testfont(fonts[font].data) then
  414. _graphresult:=setupfont(font)
  415. else
  416. begin
  417. _graphresult:=grInvalidFont;
  418. akttextinfo.font:=DefaultFont;
  419. freemem(fonts[font].data,filesize(f));
  420. end;
  421. close(f);
  422. end;
  423. end;
  424. procedure SetUserCharSize(Multx,Divx,Multy,Divy : word);
  425. begin
  426. _graphresult:=grOk;
  427. if not isgraphmode then
  428. begin
  429. _graphresult:=grnoinitgraph;
  430. exit;
  431. end;
  432. aktmultx:=Multx;
  433. aktdivx:=Divx;
  434. aktmulty:=Multy;
  435. aktdivy:=Divy;
  436. end;
  437. {
  438. $Log$
  439. Revision 1.3 1998-11-23 10:04:19 pierre
  440. * pieslice and sector work now !!
  441. * bugs in text writing removed
  442. + scaling for defaultfont added
  443. + VertDir for default font added
  444. * RestoreCRTMode corrected
  445. Revision 1.2 1998/11/18 09:31:42 pierre
  446. * changed color scheme
  447. all colors are in RGB format if more than 256 colors
  448. + added 24 and 32 bits per pixel mode
  449. (compile with -dDEBUG)
  450. 24 bit mode with banked still as problems on pixels across
  451. the bank boundary, but works in LinearFrameBufferMode
  452. Look at install/demo/nmandel.pp
  453. Revision 1.1.1.1 1998/03/25 11:18:42 root
  454. * Restored version
  455. Revision 1.3 1998/01/26 11:58:41 michael
  456. + Added log at the end
  457. Working file: rtl/dos/ppi/text.ppi
  458. description:
  459. ----------------------------
  460. revision 1.2
  461. date: 1997/12/01 12:21:34; author: michael; state: Exp; lines: +14 -0
  462. + added copyright reference in header.
  463. ----------------------------
  464. revision 1.1
  465. date: 1997/11/27 08:33:51; author: michael; state: Exp;
  466. Initial revision
  467. ----------------------------
  468. revision 1.1.1.1
  469. date: 1997/11/27 08:33:51; author: michael; state: Exp; lines: +0 -0
  470. FPC RTL CVS start
  471. =============================================================================
  472. }