2
0

bullet.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. {
  2. This file is part of the Free Pascal run time library.
  3. A file in Amiga system run time library.
  4. Copyright (c) 1998-2003 by Nils Sjoholm
  5. member of the Amiga RTL development team.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {
  13. History:
  14. Added the defines use_amiga_smartlink and
  15. use_auto_openlib. Implemented openingcode
  16. for the library
  17. 13 Jan 2003.
  18. Changed startcode for library.
  19. 1 Feb 2003.
  20. Changed integer > smallint,
  21. cardinal > longword.
  22. 09 Feb 2003.
  23. [email protected] Nils Sjoholm
  24. }
  25. {$I useamigasmartlink.inc}
  26. {$ifdef use_amiga_smartlink}
  27. {$smartlink on}
  28. {$endif use_amiga_smartlink}
  29. unit bullet;
  30. INTERFACE
  31. uses exec, utility;
  32. type
  33. { A GlyphEngine must be acquired via OpenEngine and is read-only }
  34. pGlyphEngine = ^tGlyphEngine;
  35. tGlyphEngine = record
  36. gle_Library : pLibrary; { engine library }
  37. gle_Name : STRPTR; { library basename: e.g. "bullet" }
  38. { private library data follows... }
  39. end;
  40. FIXED = Longint; { 32 bit signed w/ 16 bits of fraction }
  41. pGlyphMap = ^tGlyphMap;
  42. tGlyphMap = record
  43. glm_BMModulo, { # of bytes in row: always multiple of 4 }
  44. glm_BMRows, { # of rows in bitmap }
  45. glm_BlackLeft, { # of blank pixel columns at left }
  46. glm_BlackTop, { # of blank rows at top }
  47. glm_BlackWidth, { span of contiguous non-blank columns }
  48. glm_BlackHeight : WORD; { span of contiguous non-blank rows }
  49. glm_XOrigin, { distance from upper left corner of bitmap }
  50. glm_YOrigin : FIXED; { to initial CP, in fractional pixels }
  51. glm_X0, { approximation of XOrigin in whole pixels }
  52. glm_Y0, { approximation of YOrigin in whole pixels }
  53. glm_X1, { approximation of XOrigin + Width }
  54. glm_Y1 : smallint; { approximation of YOrigin + Width }
  55. glm_Width : FIXED; { character advance, as fraction of em width }
  56. glm_BitMap : Pointer; { actual glyph bitmap }
  57. end;
  58. pGlyphWidthEntry = ^tGlyphWidthEntry;
  59. tGlyphWidthEntry = record
  60. gwe_Node : tMinNode; { on list returned by OT_WidthList inquiry }
  61. gwe_Code : WORD; { entry's character code value }
  62. gwe_Width : FIXED; { character advance, as fraction of em width }
  63. end;
  64. const
  65. { Level 0 entries never appear in the .otag tag list, but appear in font
  66. * specifications }
  67. OT_Level0 = TAG_USER;
  68. { Level 1 entries are required to exist in the .otag tag list }
  69. OT_Level1 = (TAG_USER OR $1000);
  70. { Level 2 entries are optional typeface metric tags }
  71. OT_Level2 = (TAG_USER OR $2000);
  72. { Level 3 entries are required for some OT_Engines }
  73. OT_Level3 = (TAG_USER OR $3000);
  74. { Indirect entries are at (tag address + data offset) }
  75. OT_Indirect = $8000;
  76. {******************************************************************}
  77. { font specification and inquiry tags }
  78. { ! tags flagged with an exclaimation mark are valid for
  79. * specification.
  80. * ? tags flagged with a question mark are valid for inquiry
  81. *
  82. * fixed binary numbers are encoded as 16 bits of integer and
  83. * 16 bits of fraction. Negative values are indicated by twos
  84. * complement of all 32 bits.
  85. }
  86. { ! OT_DeviceDPI specifies the target device dots per inch -- X DPI is
  87. * in the high word, Y DPI in the low word. }
  88. OT_DeviceDPI = (OT_Level0 OR $01); { == TA_DeviceDPI }
  89. { ! OT_DotSize specifies the target device dot size as a percent of
  90. * it's resolution-implied size -- X percent in high word, Y percent
  91. * in low word. }
  92. OT_DotSize = (OT_Level0 OR $02);
  93. { ! OT_PointHeight specifies the requested point height of a typeface,
  94. * specifically, the height and nominal width of the em-square.
  95. * The point referred to here is 1/72". It is encoded as a fixed
  96. * binary number. }
  97. OT_PointHeight = (OT_Level0 OR $08);
  98. { ! OT_SetFactor specifies the requested set width of a typeface.
  99. * It distorts the width of the em-square from that specified by
  100. * OT_PointHeight. To compensate for a device with different
  101. * horizontal and vertical resolutions, OT_DeviceDPI should be used
  102. * instead. For a normal aspect ratio, set to 1.0 (encoded as
  103. * $00010000). This is the default value. }
  104. OT_SetFactor = (OT_Level0 OR $09);
  105. { ! OT_Shear... specifies the Sine and Cosine of the vertical stroke
  106. * angle, as two fixed point binary fractions. Both must be specified:
  107. * first the Sine and then the Cosine. Setting the sine component
  108. * changes the Shear to an undefined value, setting the cosine
  109. * component completes the Shear change to the new composite value.
  110. * For no shear, set to 0.0, 1.0 (encoded as $00000000, $00010000).
  111. * This is the default value. }
  112. OT_ShearSin = (OT_Level0 OR $0a);
  113. OT_ShearCos = (OT_Level0 OR $0b);
  114. { ! OT_Rotate... specifies the Sine and Cosine of the baselin rotation
  115. * angle, as two fixed point binary fractions. Both must be specified:
  116. * first the Sine and then the Cosine. Setting the sine component
  117. * changes the Shear to an undefined value, setting the cosine
  118. * component completes the Shear change to the new composite value.
  119. * For no shear, set to 0.0, 1.0 (encoded as $00000000, $00010000).
  120. * This is the default value. }
  121. OT_RotateSin = (OT_Level0 OR $0c);
  122. OT_RotateCos = (OT_Level0 OR $0d);
  123. { ! OT_Embolden... specifies values to algorithimically embolden -- or,
  124. * when negative, lighten -- the glyph. It is encoded as a fixed point
  125. * binary fraction of the em-square. The X and Y components can be
  126. * changed indendently. For normal characters, set to 0.0, 0.0
  127. * (encoded as $00000000, $00000000). This is the default value. }
  128. OT_EmboldenX = (OT_Level0 OR $0e);
  129. OT_EmboldenY = (OT_Level0 OR $0f);
  130. { ! OT_PointSize is an old method of specifying the point size,
  131. * encoded as (points * 16). }
  132. OT_PointSize = (OT_Level0 OR $10);
  133. { ! OT_GlyphCode specifies the glyph (character) code to use with
  134. * subsequent operations. For example, this is the code for an
  135. * OT_Glyph inquiry }
  136. OT_GlyphCode = (OT_Level0 OR $11);
  137. { ! OT_GlyphCode2 specifies the second glyph code. For example,
  138. * this is the right glyph of the two glyphs of an OT_KernPair
  139. * inquiry }
  140. OT_GlyphCode2 = (OT_Level0 OR $12);
  141. { ! OT_GlyphWidth specifies a specific width for a glyph.
  142. * It sets a specific escapement (advance) width for subsequent
  143. * glyphs. It is encoded as a fixed binary fraction of the em-square.
  144. * To revert to using the font-defined escapement for each glyph, set
  145. * to 0.0 (encoded as $00000000). This is the default value. }
  146. OT_GlyphWidth = (OT_Level0 OR $13);
  147. { ! OT_OTagPath and
  148. * ! OT_OTagList specify the selected typeface. Both must be specified:
  149. * first the Path and then the List. Setting the path name changes
  150. * changes the typeface to an undefined value, providing the List
  151. * completes the typeface selection to the new typeface. OTagPath
  152. * is the null terminated full file path of the .otag file associated
  153. * with the typeface. OTagList is a memory copy of the processed
  154. * contents of that .otag file (i.e. with indirections resolved).
  155. * There are no default values for the typeface. }
  156. OT_OTagPath = (OT_Level0 OR OT_Indirect OR $14);
  157. OT_OTagList = (OT_Level0 OR OT_Indirect OR $15);
  158. { ? OT_GlyphMap supplies a read-only struct GlyphMap pointer that
  159. * describes a bitmap for a glyph with the current attributes. }
  160. OT_GlyphMap = (OT_Level0 OR OT_Indirect OR $20);
  161. { ? OT_WidthList supplies a read-only struct MinList of struct
  162. * GlyphWidthEntry nodes for glyphs that are defined from GlyphCode
  163. * to GlyphCode2, inclusive. The widths are represented as fixed
  164. * binary fractions of the em-square, ignoring any effect of
  165. * SetFactor or GlyphWidth. A width would need to be converted to
  166. * a distance along the baseline in device units by the
  167. * application. }
  168. OT_WidthList = (OT_Level0 OR OT_Indirect OR $21);
  169. { ? OT_...KernPair supplies the kern adjustment to be added to the
  170. * current position after placement of the GlyphCode glyph and
  171. * before placement of the GlyphCode2 glyph. Text kern pairs are
  172. * for rendering body text. Display kern pairs are generally
  173. * tighter values for display (e.g. headline) purposes. The
  174. * adjustment is represented as a fixed binary fraction of the
  175. * em-square, ignoring any effect of SetFactor. This number would
  176. * need to be converted to a distance along the baseline in device
  177. * units by the application. }
  178. OT_TextKernPair = (OT_Level0 OR OT_Indirect OR $22);
  179. OT_DesignKernPair = (OT_Level0 OR OT_Indirect OR $23);
  180. { ? OT_Underlined is an unsigned word which is used to request
  181. * algorithimic underlining for the engine when rendering the glyph.
  182. * Bullet.library currently does not support this tag, though it
  183. * may be used by other engines in the future. The default for
  184. * any engine which supports this tag must be OTUL_None. Engines which
  185. * do not support this tag should return an appropriate OTERR value.
  186. *
  187. * As of V39, diskfont.library will request underlining if specified
  188. * in the TextAttr, or TTextAttr passed to OpenDiskFont(). Diskfont
  189. * will first request Broken underlining (like the Text() function
  190. * does when SetSoftStyle() is used), and then Solid underlining if
  191. * the engine returns an error. If the engine returns an error for
  192. * both, then diskfont.library attempts to find, or create the best
  193. * non-underlined font that it can. }
  194. OT_UnderLined = (OT_Level0 OR $24);
  195. OTUL_None = 0;
  196. OTUL_Solid = 1;
  197. OTUL_Broken = 2;
  198. OTUL_DoubleSolid = 3;
  199. OUTL_DoubleBroken = 4;
  200. { ? OT_StrikeThrough is a boolean which is used to request
  201. * algorithimic strike through when rendering the glyph.
  202. * Bullet.library currently does not support this tag, though it
  203. * may be used by other engines in the future. The default for
  204. * any engined which supports this tag must be FALSE. Engines which
  205. * do not support this tag should return an appropriate OTERR value. }
  206. OT_StrikeThrough = (OT_Level0 OR $25);
  207. {******************************************************************}
  208. { .otag tags }
  209. { suffix for files in FONTS: that contain these tags }
  210. OTSUFFIX : PChar = '.otag';
  211. { OT_FileIdent both identifies this file and verifies its size.
  212. * It is required to be the first tag in the file. }
  213. OT_FileIdent = (OT_Level1 OR $01);
  214. { OT_Engine specifies the font engine this file is designed to use }
  215. OT_Engine = (OT_Level1 OR OT_Indirect OR $02);
  216. OTE_Bullet = 'bullet';
  217. { OT_Family is the family name of this typeface }
  218. OT_Family = (OT_Level1 OR OT_Indirect OR $03);
  219. { The name of this typeface is implicit in the name of the .otag file }
  220. { OT_BName is used to find the bold variant of this typeface }
  221. OT_BName = (OT_Level2 OR OT_Indirect OR $05);
  222. { OT_IName is used to find the italic variant of this typeface }
  223. OT_IName = (OT_Level2 OR OT_Indirect OR $06);
  224. { OT_BIName is used to find the bold italic variant of this typeface }
  225. OT_BIName = (OT_Level2 OR OT_Indirect OR $07);
  226. { OT_SymSet is used to select the symbol set that has the OT_YSizeFactor
  227. * described here. Other symbol sets might have different extremes }
  228. OT_SymbolSet = (OT_Level1 OR $10);
  229. { OT_YSizeFactor is a ratio to assist in calculating the Point height
  230. * to BlackHeight relationship -- high word: Point height term, low
  231. * word: Black height term -- pointSize = ysize*<high>/<low> }
  232. OT_YSizeFactor = (OT_Level1 OR $11);
  233. { OT_SpaceWidth specifies the width of the space character relative
  234. * to the character height }
  235. OT_SpaceWidth = (OT_Level2 OR $12);
  236. { OT_IsFixed is a boolean indicating that all the characters in the
  237. * typeface are intended to have the same character advance }
  238. OT_IsFixed = (OT_Level2 OR $13);
  239. { OT_SerifFlag is a boolean indicating if the character has serifs }
  240. OT_SerifFlag = (OT_Level1 OR $14);
  241. { OT_StemWeight is an unsigned byte indicating the weight of the character }
  242. OT_StemWeight = (OT_Level1 OR $15);
  243. OTS_UltraThin = 8; { 0- 15 }
  244. OTS_ExtraThin = 24; { 16- 31 }
  245. OTS_Thin = 40; { 32- 47 }
  246. OTS_ExtraLight = 56; { 48- 63 }
  247. OTS_Light = 72; { 64- 79 }
  248. OTS_DemiLight = 88; { 80- 95 }
  249. OTS_SemiLight = 104; { 96-111 }
  250. OTS_Book = 120; { 112-127 }
  251. OTS_Medium = 136; { 128-143 }
  252. OTS_SemiBold = 152; { 144-159 }
  253. OTS_DemiBold = 168; { 160-175 }
  254. OTS_Bold = 184; { 176-191 }
  255. OTS_ExtraBold = 200; { 192-207 }
  256. OTS_Black = 216; { 208-223 }
  257. OTS_ExtraBlack = 232; { 224-239 }
  258. OTS_UltraBlack = 248; { 240-255 }
  259. { OT_SlantStyle is an unsigned byte indicating the font posture }
  260. OT_SlantStyle = (OT_Level1 OR $16);
  261. OTS_Upright = 0;
  262. OTS_Italic = 1; { Oblique, Slanted, etc. }
  263. OTS_LeftItalic = 2; { Reverse Slant }
  264. { OT_HorizStyle is an unsigned byte indicating the appearance width }
  265. OT_HorizStyle = (OT_Level1 OR $17);
  266. OTH_UltraCompressed = 16; { 0- 31 }
  267. OTH_ExtraCompressed = 48; { 32- 63 }
  268. OTH_Compressed = 80; { 64- 95 }
  269. OTH_Condensed = 112; { 96-127 }
  270. OTH_Normal = 144; { 128-159 }
  271. OTH_SemiExpanded = 176; { 160-191 }
  272. OTH_Expanded = 208; { 192-223 }
  273. OTH_ExtraExpanded = 240; { 224-255 }
  274. { OT_SpaceFactor specifies the width of the space character relative
  275. * to the character height }
  276. OT_SpaceFactor = (OT_Level2 OR $18);
  277. { OT_InhibitAlgoStyle indicates which ta_Style bits, if any, should
  278. * be ignored even if the font does not already have that quality.
  279. * For example, if FSF_BOLD is set and the typeface is not bold but
  280. * the user specifies bold, the application or diskfont library is
  281. * not to use OT_Embolden to achieve a bold result. }
  282. OT_InhibitAlgoStyle = (OT_Level2 OR $19);
  283. { OT_AvailSizes is an indirect pointer to sorted UWORDs, 0th is count }
  284. OT_AvailSizes = (OT_Level1 OR OT_Indirect OR $20);
  285. OT_MAXAVAILSIZES = 20; { no more than 20 sizes allowed }
  286. { OT_SpecCount is the count number of parameters specified here }
  287. OT_SpecCount = (OT_Level1 OR $100);
  288. { Specs can be created as appropriate for the engine by ORing in the
  289. * parameter number (1 is first, 2 is second, ... up to 15th) }
  290. OT_Spec = (OT_Level1 OR $100);
  291. { OT_Spec1 is the (first) parameter to the font engine to select
  292. * this particular typeface }
  293. OT_Spec1 = (OT_Level1 OR $101) ;
  294. const
  295. { PRELIMINARY }
  296. OTERR_Failure = -1; { catch-all for error }
  297. OTERR_Success = 0 ; { no error }
  298. OTERR_BadTag = 1 ; { inappropriate tag for function }
  299. OTERR_UnknownTag = 2 ; { unknown tag for function }
  300. OTERR_BadData = 3 ; { catch-all for bad tag data }
  301. OTERR_NoMemory = 4 ; { insufficient memory for operation }
  302. OTERR_NoFace = 5 ; { no typeface currently specified }
  303. OTERR_BadFace = 6 ; { typeface specification problem }
  304. OTERR_NoGlyph = 7 ; { no glyph specified }
  305. OTERR_BadGlyph = 8 ; { bad glyph code or glyph range }
  306. OTERR_NoShear = 9 ; { shear only partially specified }
  307. OTERR_NoRotate = 10; { rotate only partially specified }
  308. OTERR_TooSmall = 11; { typeface metrics yield tiny glyphs }
  309. OTERR_UnknownGlyph = 12; { glyph not known by engine }
  310. VAR BulletBase : pLibrary;
  311. const
  312. BULLETNAME : PChar = 'bullet.library';
  313. PROCEDURE CloseEngine(glyphEngine : pGlyphEngine);
  314. FUNCTION ObtainInfoA(glyphEngine : pGlyphEngine; tagList : pTagItem) : ULONG;
  315. FUNCTION OpenEngine : pGlyphEngine;
  316. FUNCTION ReleaseInfoA(glyphEngine : pGlyphEngine; tagList : pTagItem) : ULONG;
  317. FUNCTION SetInfoA(glyphEngine : pGlyphEngine; tagList : pTagItem) : ULONG;
  318. {Here we read how to compile this unit}
  319. {You can remove this include and use a define instead}
  320. {$I useautoopenlib.inc}
  321. {$ifdef use_init_openlib}
  322. procedure InitBULLETLibrary;
  323. {$endif use_init_openlib}
  324. {This is a variable that knows how the unit is compiled}
  325. var
  326. BULLETIsCompiledHow : longint;
  327. IMPLEMENTATION
  328. {
  329. If you don't use array of const then just remove tagsarray
  330. }
  331. uses
  332. {$ifndef dont_use_openlib}
  333. msgbox;
  334. {$endif dont_use_openlib}
  335. PROCEDURE CloseEngine(glyphEngine : pGlyphEngine);
  336. BEGIN
  337. ASM
  338. MOVE.L A6,-(A7)
  339. MOVEA.L glyphEngine,A0
  340. MOVEA.L BulletBase,A6
  341. JSR -036(A6)
  342. MOVEA.L (A7)+,A6
  343. END;
  344. END;
  345. FUNCTION ObtainInfoA(glyphEngine : pGlyphEngine; tagList : pTagItem) : ULONG;
  346. BEGIN
  347. ASM
  348. MOVE.L A6,-(A7)
  349. MOVEA.L glyphEngine,A0
  350. MOVEA.L tagList,A1
  351. MOVEA.L BulletBase,A6
  352. JSR -048(A6)
  353. MOVEA.L (A7)+,A6
  354. MOVE.L D0,@RESULT
  355. END;
  356. END;
  357. FUNCTION OpenEngine : pGlyphEngine;
  358. BEGIN
  359. ASM
  360. MOVE.L A6,-(A7)
  361. MOVEA.L BulletBase,A6
  362. JSR -030(A6)
  363. MOVEA.L (A7)+,A6
  364. MOVE.L D0,@RESULT
  365. END;
  366. END;
  367. FUNCTION ReleaseInfoA(glyphEngine : pGlyphEngine; tagList : pTagItem) : ULONG;
  368. BEGIN
  369. ASM
  370. MOVE.L A6,-(A7)
  371. MOVEA.L glyphEngine,A0
  372. MOVEA.L tagList,A1
  373. MOVEA.L BulletBase,A6
  374. JSR -054(A6)
  375. MOVEA.L (A7)+,A6
  376. MOVE.L D0,@RESULT
  377. END;
  378. END;
  379. FUNCTION SetInfoA(glyphEngine : pGlyphEngine; tagList : pTagItem) : ULONG;
  380. BEGIN
  381. ASM
  382. MOVE.L A6,-(A7)
  383. MOVEA.L glyphEngine,A0
  384. MOVEA.L tagList,A1
  385. MOVEA.L BulletBase,A6
  386. JSR -042(A6)
  387. MOVEA.L (A7)+,A6
  388. MOVE.L D0,@RESULT
  389. END;
  390. END;
  391. const
  392. { Change VERSION and LIBVERSION to proper values }
  393. VERSION : string[2] = '0';
  394. LIBVERSION : longword = 0;
  395. {$ifdef use_init_openlib}
  396. {$Info Compiling initopening of bullet.library}
  397. {$Info don't forget to use InitBULLETLibrary in the beginning of your program}
  398. var
  399. bullet_exit : Pointer;
  400. procedure ClosebulletLibrary;
  401. begin
  402. ExitProc := bullet_exit;
  403. if BulletBase <> nil then begin
  404. CloseLibrary(BulletBase);
  405. BulletBase := nil;
  406. end;
  407. end;
  408. procedure InitBULLETLibrary;
  409. begin
  410. BulletBase := nil;
  411. BulletBase := OpenLibrary(BULLETNAME,LIBVERSION);
  412. if BulletBase <> nil then begin
  413. bullet_exit := ExitProc;
  414. ExitProc := @ClosebulletLibrary;
  415. end else begin
  416. MessageBox('FPC Pascal Error',
  417. 'Can''t open bullet.library version ' + VERSION + #10 +
  418. 'Deallocating resources and closing down',
  419. 'Oops');
  420. halt(20);
  421. end;
  422. end;
  423. begin
  424. BULLETIsCompiledHow := 2;
  425. {$endif use_init_openlib}
  426. {$ifdef use_auto_openlib}
  427. {$Info Compiling autoopening of bullet.library}
  428. var
  429. bullet_exit : Pointer;
  430. procedure ClosebulletLibrary;
  431. begin
  432. ExitProc := bullet_exit;
  433. if BulletBase <> nil then begin
  434. CloseLibrary(BulletBase);
  435. BulletBase := nil;
  436. end;
  437. end;
  438. begin
  439. BulletBase := nil;
  440. BulletBase := OpenLibrary(BULLETNAME,LIBVERSION);
  441. if BulletBase <> nil then begin
  442. bullet_exit := ExitProc;
  443. ExitProc := @ClosebulletLibrary;
  444. BULLETIsCompiledHow := 1;
  445. end else begin
  446. MessageBox('FPC Pascal Error',
  447. 'Can''t open bullet.library version ' + VERSION + #10 +
  448. 'Deallocating resources and closing down',
  449. 'Oops');
  450. halt(20);
  451. end;
  452. {$endif use_auto_openlib}
  453. {$ifdef dont_use_openlib}
  454. begin
  455. BULLETIsCompiledHow := 3;
  456. {$Warning No autoopening of bullet.library compiled}
  457. {$Warning Make sure you open bullet.library yourself}
  458. {$endif dont_use_openlib}
  459. END. (* UNIT BULLET *)