# The ScrnFont interface

A `ScrnFont.T` is a handle on a typeface that is valid for some particular screentype, called the owner of the handle. All handles have names, which are highly conventionalized strings encoding the size, style, and other properties of the typeface.

    INTERFACE ScrnFont;

    IMPORT ScrnPixmap, Rect, TrestleComm, Font, Fingerprint;

    EXCEPTION Failure;

### Obtaining handles from the oracle

    TYPE
      Oracle = Private OBJECT
        METHODS
          <* LL.sup <= VBT.mu *>
          list(pat: TEXT; maxResults := 1):
            REF ARRAY OF TEXT RAISES {TrestleComm.Failure};
          match(
            family: TEXT;
            pointSize: INTEGER := 120;
            slant: Slant := Slant.Roman;
            maxResults: CARDINAL := 1;
            weightName: TEXT := AnyMatch;
            version: TEXT := "";
            foundry: TEXT := AnyMatch;
            width: TEXT := AnyMatch;
            pixelsize: INTEGER := AnyValue;
            hres, vres: INTEGER := ScreenTypeResolution;
            spacing: Spacing := Spacing.Any;
            averageWidth: INTEGER := AnyValue;
            charsetRegistry: TEXT := "ISO8859";
            charsetEncoding: TEXT := "1")
          : REF ARRAY OF TEXT RAISES {TrestleComm.Failure};
          lookup(name: TEXT): T
            RAISES {Failure, TrestleComm.Failure};
          builtIn(f: Font.Predefined): T;
        END;
        Private <: ROOT;

For a screentype `st`, the field `st.font` is an `Oracle` that produces font handles owned by `st`.

The method call

     st.font.list(pat, maxResults)

returns the names of all fonts owned by `st` that match the pattern `pat`. The list of results may be truncated to length `maxResults`. A `*` matches any number of characters and a `?` matches a single character.

The arguments to the `match` method specify various font attributes, as explained below. The method call

     st.font.match(...)

returns the names of all font handles owned by `st` that match the specifications. The list of results may be truncated to the length `maxResults`. If no fonts match the specifications, the result will be either `NIL` or an empty array. Passing `AnyMatch` for a text attribute, or `AnyValue` for an integer attribute, allows any value for that attribute. For text attributes, partial text matches are also possible: a `*` matches any number of characters and `?` matches a single character.

The method call

     st.font.lookup(name)

returns the font handle owned by `st` with the given name. Generally `name` should be one of the names returned by the `list` or `match` method.

The method call

     st.font.builtIn(f)

returns the screen-dependent font valid for `st` that corresponds to the predefined screen-independent font `Font.T{f}`.

The locking level for all methods is `LL.sup <= VBT.mu`.

### Font attributes

The arguments to a font oracle list method specify font attributes whose full specifications are the ``X Logical Font Description Conventions Version 1.3'', an MIT X Consortium Standard which can be found in Part IV of X Window System by Scheifler and Gettys [XSpec] . Here they are described in brief.

The argument `family` specifies the family of the typeface. To find out what fonts your X server has, run the `xlsfonts` program. Most servers support the families `Courier`, `Helvetica`, and `Times`, among others.

The argument `pointsize` is ten times the font's size in points; e.g., 120 for a standard 12-point font.

The argument `slant` is an element of the following enumeration type:

    TYPE
      Slant = {Roman, Italic, Oblique, ReverseItalic,
        ReverseOblique, Other, Any};

whose elements have the following interpretations:

- `Roman`: Upright letters in a roman style.
- `Italic`: Clockwise slanted letters in an italic style.
- `Oblique`: Clockwise slanted letters in a roman style.
- `ReverseItalic`: Counter clockwise slanted letters in an italic style.
- `ReverseOblique`: Counter clockwise slanted letters in a roman style.
- `Other`: None of the above
- `Any`: Any of the above (including `Other`).

The argument `weightName` is the foundry's name for the font's weight; e.g., `Bold`, `DemiBold`, or `Medium`.

The argument `version` specifies the version of the X Logical Font Description Conventions that describes the format of a font's name. If the argument is omitted, Version 1.3 is assumed. (Version 1.3 is the only version as these words are written.)

The argument `foundry` specifies the X registered name for the font's foundry, e.g., `Adobe`, `B&H`, `Bitstream`, `DEC`.

The argument `width` specifies the foundry's name for the font's width; e.g., `Normal` or `Condensed`.

The argument `pixelsize` specifies the size of the font in pixels. The size in points depends on the vertical resolution of the device: A pixelsize of 20 could represent a 20-point font at 75 pixels per inch or a 10-point font at 150 pixels per inch.

The arguments `hres` and `vres` specify the horizontal and vertical screen resolution for which the font is designed, in pixels per inch.

The argument `spacing` is an element of the following enumeration:

    TYPE Spacing =
      {Proportional, Monospaced, CharCell, Any};

whose elements have the following meaning:

- `Proportional`: Character widths vary.
- `Monospaced`: Character widths are constant.
- `CharCell`: Font is self-clearing, as defined in the `VBT` interface.
- `Any`: Any of the above.

The argument `averageWidth` specifies the un-weighted arithmetic mean of the widths of all glyphs in the font, measured in tenths of a pixel.

The arguments `charsetRegistry` and `charsetEncoding` are the X names of the font's character set and encoding scheme; e.g., `ISO8859` and `1` for ISO Latin-1 fonts. See Appendix G of [XSpec] .

    CONST
      AnyMatch = "*";
      AnyValue = -1;
      ScreenTypeResolution = -2;

Passing `AnyMatch` as an argument to the `list` method matches any text value for the corresponding attribute, and `AnyValue` matches any integer value. Passing `ScreenTypeResolution` for `hres` or `vres` matches fonts whose horizontal and vertical resolutions agree with the screentype that owns the font.

### Registering fonts

Some screentypes allow the client to register fonts. The client registers the font's strike (bits) and metrics (description) with the `StrikeOracle`. The name of the font is implied by the attributes in the metrics, so the `list` and `lookup` methods will find client-registered fonts.

    TYPE
      StrikeOracle = Oracle OBJECT
        METHODS
          <* LL.sup <= VBT.mu *>
          load(strike: Strike; metrics: Metrics): T
            RAISES {Failure, TrestleComm.Failure};
        END;

The method call `st.font.load(strike, metrics)` creates a font owned by `st` with the given strike and metrics and returns a handle to it.

The `metrics` argument must define all of the initial fields of the font metrics record: `family`, `pointSize`, ..., `isAscii`, and `defaultChar`. The values `minBounds` and `maxBounds` must be provided if `charMetrics` is `NIL`; otherwise if `printWidth` is `AnyValue`, the `load` method will compute them from `charMetrics`. If any of the remaining fields have the value `AnyValue`, the `load` method will compute them.

### The handle object

    TYPE
      T <: Public;
      Public = OBJECT (*CONST*)
        id: INTEGER;
        metrics: Metrics
      END;

    TYPE StrikeFont = T OBJECT
      METHODS <* LL.sup <= VBT.mu *>
        strike(): Strike RAISES {TrestleComm.Failure}
      END;

    TYPE Strike = OBJECT
      METHODS <* LL.sup <= VBT.mu *>
        glyph(ch: INTEGER): ScrnPixmap.T;
      END;

If `f` is a `ScrnFont.T`, then `f.id` is an identifier whose interpretation depends on the screentype that owns `f` and `f.metrics` are the metrics for `f`. If in addition `f` is a `StrikeFont`, then `f.strike()` returns `f`'s strike. The screentype of the strike's pixmaps will be the screentype that owns `f`.

If `str` is a `Strike`, then `str.glyph(ch)` is the pixmap for the character `ch`. This will be empty except for characters in the range `[m.firstChar..m.lastChar]`, where `m` is the metrics (see below) for the font of which `str` is the strike.

    PROCEDURE BoundingBox(txt: TEXT; fnt: T): Rect.T;
    <* LL arbitrary *>

Return the smallest rectangle that contains the bounding boxes of the characters of `txt` if `txt` were painted in the font `fnt` with `txt`'s reference point at the origin.

    PROCEDURE BoundingBoxSub(
      READONLY txt: ARRAY OF CHAR;
      fnt: T): Rect.T;
    <* LL arbitrary *>

Like `BoundingBox` but takes an array instead of a `TEXT`.

    PROCEDURE BoundingBoxSubValid(
      READONLY txt: ARRAY OF CHAR;
      fnt: T; VAR (*OUT*) valid: BOOLEAN): Rect.T;
    <* LL arbitrary *>

Like `BoundingBoxSub` but indicates if all characters in `txt` are valid. `valid` may be set to `FALSE` even if all characters are valid, if the text wasn't checked.

    PROCEDURE TextWidth(txt: TEXT; fnt: T): INTEGER;
    <* LL arbitrary *>

Return the sum of the printing widths of the characters in `txt` in the font `fnt`.

### The raw representation

    TYPE
      CharMetric = RECORD
        printWidth: INTEGER;
        boundingBox: Rect.T;
      END;
      CharMetrics = REF ARRAY OF CharMetric;

The `printWidth` of a character is the displacement to the next character's reference point.

The `boundingBox` of a character is the smallest rectangle with sides parallel to the axes that contains the glyph of the character placed with its reference point at (0,0).

    TYPE
      Metrics = OBJECT (*CONST*)
        family: TEXT;
        pointSize: INTEGER;
        slant: Slant;
        weightName: TEXT;
        version: TEXT;
        foundry: TEXT;
        width: TEXT;
        pixelsize: INTEGER;
        hres, vres: INTEGER;
        spacing: Spacing;
        averageWidth: INTEGER;
        charsetRegistry: TEXT;
        charsetEncoding: TEXT;
        firstChar, lastChar: INTEGER;
        charMetrics: CharMetrics;
        selfClearing: BOOLEAN;
        rightKerning, leftKerning: BOOLEAN;
        isAscii: BOOLEAN;
        defaultChar: INTEGER;
        minBounds, maxBounds: CharMetric;
        ascent, descent := 0;
        fprint := Fingerprint.Zero;
      METHODS <* LL arbitrary *>
        intProp(name: TEXT; ch: INTEGER := -1): INTEGER
          RAISES {Failure};
        textProp(name: TEXT; ch: INTEGER := -1): TEXT
          RAISES {Failure};
      END;

The fields from `family` to `charSetEncoding` in the `Metrics` object specify the attributes that were defined for the `lookup` method. A value of `*` or `Any` in one of these fields means that the corresponding attribute is unknown.

The integers `firstChar` and `lastChar` are the indices of the first and last characters defined in the font.

The array `charMetrics` specifies the metrics of the individual characters. The metrics for character `ch` are in `charMetrics[ch-firstChar]`. If all characters have the same `printWidth` and `boundingBox`, then these values are stored in `minBounds` and `maxBounds` and the `charMetrics` field is `NIL`.

The flag `selfClearing` indicates whether the font is self-clearing, as defined in the `VBT` interface, and the two kerning flags indicate the present of right and left kerning in the font.

The flag `isAscii` indicates that character codes 32-126 (base 10) have their normal ASCII meanings.

The integer `defaultChar` is the code for the recommended character to display in the place of a character that isn't defined for the font.

The rectangles `minBounds.boundingBox` and `maxBounds.boundingBox` contain the meet and join, respectively, of the bounding boxes of all characters in the font when they are positioned with their reference points at (0, 0). The values `minBounds.printWidth` and `maxBounds.printWidth` are the minimum and maximum printing widths for all characters in the font.

The method call `m.intProp(nm)` returns the integer value of the font attribute named `nm`, or raises `Failure` if this attribute is not defined for `m`. The method call `m.intProp(nm, ORD(ch))` returns the integer value of the font attribute named `nm` for the character `ch`, or raises `Failure` if this attribute is not defined for `(m, ch)`. The `textProp` method is similar.

The set of attributes returned by the metrics methods depend on the font. Fonts that are owned by X screentypes support the attributes defined in Part IV of X Window System (op. cit.); we recommend that other fonts support them too. (To read an X font attribute whose type is an X atom, use the `textProp` method, which returns the name of the atom.)

The fprint field, if non-zero, holds a fingerprint for the metrics, which can be used to quickly determine if two Metrics are the same.

The ascent and descent fields contain the recommended spacing in pixels above and below the baseline; the sum is the recommended base-line skip.

    END ScrnFont.