Package limn.graphics

Interface FontLoader

Functional Interface:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

@FunctionalInterface public interface FontLoader
Registers a font file the application ships, so its family becomes usable by name.

Installed by the backend through Fonts.installLoader(limn.graphics.FontLoader); UNAVAILABLE is the headless default, and it refuses rather than pretending a family exists.

This is the only way a face that is neither bundled in the backend nor installed in the operating system can enter the font stack. Without it an application that ships its own typeface has to ask the user to install it, and a capture or test that names such a family silently gets the default face instead, a difference nothing downstream can see.

It is also where Fonts.preload(java.lang.String) reaches the backend: preload(java.lang.String, java.lang.Runnable) reads a family's faces ahead of their first use, and its default, for a loader that keeps nothing resident, reads nothing. withdraw(java.lang.String, java.lang.Runnable) takes back a request a later choice overtook.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final FontLoader
    No backend / headless: there is nothing that can parse a font file.
  • Method Summary

    Modifier and Type
    Method
    Description
    load(Path file)
    Reads the faces in one font file and registers them under their own family name.
    default void
    preload(String family, Runnable whenResident)
    Makes family's regular and bold faces resident without reading a font file on the UI thread, so that the first measure or paint in that family finds them rather than reading them inside its frame.
    default void
    withdraw(String family, Runnable whenResident)
    Takes back a preload(java.lang.String, java.lang.Runnable) request: whoever passed whenResident for family no longer wants the faces.
  • Field Details

    • UNAVAILABLE

      static final FontLoader UNAVAILABLE
      No backend / headless: there is nothing that can parse a font file.
  • Method Details

    • load

      String load(Path file)
      Reads the faces in one font file and registers them under their own family name.

      Synchronous, and on the calling thread. What is read here is the file's name table (the family and style strings, kilobytes), not its glyphs; those are parsed on first use, the same way an operating-system face is. Registration has to complete before it returns, because the caller's next act is to name the family in a widget or in Fonts.setDefaultFamily(java.lang.String), and a family that is not registered yet resolves to the default face.

      Parameters:
      file - font file (TrueType, OpenType, or a collection); a relative path resolves against the process working directory
      Returns:
      the family name the faces registered under; pass this to Fonts.setDefaultFamily(java.lang.String) or to Font, rather than assuming the name from the file name, which need not match what the file declares
      Throws:
      UncheckedIOException - if the file cannot be read
      MalformedContentException - if it carries no usable face
      UnsupportedOperationException - if no backend is installed
    • preload

      default void preload(String family, Runnable whenResident)
      Makes family's regular and bold faces resident without reading a font file on the UI thread, so that the first measure or paint in that family finds them rather than reading them inside its frame. What Fonts.preload(java.lang.String) and Fonts.setDefaultFamilyWhenResident(java.lang.String) call; an application calls those.

      Called on the UI thread. An implementation reads on a worker and runs whenResident on the UI thread once the faces are resident, and also when there is nothing to read: a family it carries itself, one already resident, one it does not know. It runs it exactly once and never inside this call, so a caller may change its own state there without re-entering this; it need not run it at all once the backend has shut down, when there is no UI thread left to run it on, or once the request has been withdrawn. Two requests for one family may share one read, and a read once started need not stop: what withdraw takes back is the request.

      The default reads nothing and runs whenResident on the UI thread's next turn, which is right for a loader that keeps no face resident, UNAVAILABLE among them.

      Parameters:
      family - the family name, as a Font names it; never blank and never Font.DEFAULT_FAMILY, which Fonts answers itself
      whenResident - what to run on the UI thread once the faces are resident
    • withdraw

      default void withdraw(String family, Runnable whenResident)
      Takes back a preload(java.lang.String, java.lang.Runnable) request: whoever passed whenResident for family no longer wants the faces. What Fonts calls on the request of a Fonts.setDefaultFamilyWhenResident(java.lang.String) that a later choice overtook; an application calls neither.

      Called on the UI thread. An implementation need not run whenResident any more, and need not stop a read already under way, which may serve another request for the family too. A read that lands with no request left on it, for a family nothing draws in, is one nobody wants: an implementation that keeps a bounded number of faces resident keeps its faces only in room it can make without letting go of a face in use, and has nothing laid out again for them. That is what keeps a font picker stepped through a list from re-laying out the UI once per entry it passed, and from evicting the family the UI is drawn in.

      The default does nothing, which is right for a loader that keeps no face resident: the callback still runs, and Fonts ignores it.

      Parameters:
      family - the family named in the request, as it was passed to preload(java.lang.String, java.lang.Runnable)
      whenResident - the callback passed with it, the same instance