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