Font issues v0.1
Disclaimer
I am by no means an expert on the following
subjects I am talking about: Fonts, GNUstep and
the english language. So bear this in mind before
pointing me in the right direction:-)
Contents
- Introduction
- How it works now
- Very short overview
- GUI side
- Backend
- Connection between backend and frontend
- Font naming
- Requirements
- Configuration
- Installation/configuration
- running system configuration
- Daily usage
- Proposal for new implementation
- Questions
- non-technical questions
- screen vs. printer fonts
1. Introduction
First a short overview of how the current font system
works in GNUstep is given. Someone who know how the
current font system works can skip this part.
(But comments are welcome because I am new to
this.)
The second part consists of the short list of what
I expect from the font system. This part
should be extended and be made more detailed.
The next part describes a suggestion
of how the font system could be implemented.
This is very high level and in the process of
being written.
2. How it works now
2.1 Very short overview
The font system divided over two components:
- The gui (AppKit) component
- The graphical backend.
2.2 GUI side
The responsibility of the GUI side of the Font system is
more of an administrative kind. It provides applications
with roughly the following API
- Find out which fonts are available. (GUI will ask the backend)
- Get a font object.
- Get all kind of font info, such as kerning,
widths, bounding boxes etcetera. (Calculated from information
provided by the backend)
- Bold/Unbold Italic/UnItalic a font etcetera.
- And of course it has the possibility to set a font.
So the lowlevel functionality of this API is delegated to the backend.
The API is provided by the classes
NSFont, NSFontManager and
NSFontPanel.
These classes are described in the OpenStep API specification.
The GUI component also contains the private classes
GSFontInfo and
GSFontEnumerator.
Those private classes do two things:
- They provide the link between the GUI and the backend.
- They implement functionality that is shared between
the different backends.
2.3 Backend
The responsibilities can be divided into two parts
- Providing information to the GUI frontend.
- A list of available fonts.
- Provide a real font object for a name and transformation.
- For a font all the font characterstics, such as bounding box etc.
- Use the font for
- Making it the current font.
- Rendering characters/strings on the screen.
2.4 Connection between backend and frontend
Care has been taken to minimize the dependency of the frontend on
the backend. All the functionality that the frontend need is
declared in the two private classes GSFontInfo and
GSFontEnumerator. The backend will subclass these
two classes and implement the methods that the
GSFont[Info|Enumerator]
classes need.
The initializers of the
GSFont[Font|Enumerator]
classes will upon initialization return instances of the
subclasses provided by the backend.
The GSFont* classes know what the subclasses are because
the backend initialization routine provides the GSFont* classes with
this information.
A pictorial representation of this for the NSFont class is
\
+--------+ +-------------+ |
| NSFont | --------> | GSFontInfo | |
+--------+-+ +-------------+ |
| fontname | | fontname | |
| matrix | | familyname | > GUI
+----------+ | matrix | |
| fontmetrics | |
| fntDict (*) | |
+-------------+ |
| / (*) not used at
| the moment
/ \
---
| \
+------------+ |
| XGFontInfo | |
+------------+ |
| implements | > backend
| all almost | |
| logic | |
+------------+ |
/
A similar picture can be drawn for the GSFontEnumerator class.
2.5 Font naming
The backend knows what fonts are available and provides
the frontend, by means of GSFontEnumerator,
with the names of the font it knows.
3. Requirements
Before thinking of how to reorganize the font system
we should have some idea of how the `user' want the
system to behave. For user we should not necessary read
a human user. When this distinction is important it will
be explicitly stated.
The requirements of the font system can be roughly
divided into two categories: daily usage, installation/configuration.
3.1 Configuration
3.1.1 installation/configuration
The installation of GNUstep should be as easy as possible.
A consequence of this is that on a normal computer system
no configuration is required. In order to achieve this
starting the GNUstep system should be able to:
- Detect all fonts suitable for the different backends
that are installed. This includes but is not limited to:
- For the xgps backend all Xlib fonts.
- All T1 fonts installed on the system in the
default place for the underlying operating system.
- When a backend provides support for TrueType
or Opentype fonts it should detect these.
- Use font mappings that can be found on the
the underlying operating systems. An example of
such a mapping is the
FontMap
file provided by ghostscript.
- Provide a minimum
set of standard fonts, at least:
- The Helvetica family consisting of the
regular, bold, italic, bold-italic variety.
- The Courier family consisting of the
regular, bold, italic, bold-italic variety
This could be done by either including these
default fonts in GNUstep, or automatically
map the default fonts to fonts found on
the system.
3.1.2 running system configuration
After the initial installation the user should
be able to add fonts. When these fonts are added to
the underlying operating system, GNUstep will pick them
up after restarting GNUstep. It should also be possible
to install fonts in a running GNUstep system, but for
this a special tool will be needed. (GNUstep can not guess
that the operating system acquired a new font.)
Configuration should not be necessary. But for the
advanced user configuration should be possible to a high
degree. Examples of what should be customized includes
- Mapping GNUstep font names, as the user sees them
in the font panel, to fonts that the fontsystem has
detected. For example, my system does not include
a Helvetica font. But ghostscript maps the
Helvetica fonts to the NimbusSanL fonts.
These kind of mappings should be configurable.
- Disabling some fonts in order to remove unwanted
fonts.
- Provide a way to influence the way that a font
is displayed on the screen. This means that
the connection between a NSFont and its corresponding
screen font can be customized. The customization
depends not only on the font but also on the point
size and on the current transformation matrix.
The customization includes per (font,size/matrix) combination
- Using a specific screenfont
- Using the Xlib mechanism, or any other
specific font renderer.
- Using antialiasing, and which form of it.
- Or some other parameters I did not think of.
This includes quite a bit of backend configuration.
And these changes should be relativily easy to make.
That means that if you decide to turn antialiasing
on for fonts sizes greater than 16points it should
not be necessary to change every individual pointsize
bigger than 16point.
- Provide a way to configure the printerfonts.
This is a subject that I do not understand.
3.2 daily usage
When using the fonts the user should not see anything
from the configuration process. Also the user should
not be restricted by what GNUstep has found. That means that
- The fonts are presented to the user in the way he
expects under GNUstep.
That is, in the FontPanel as a family/face name pair.
- Every font is printable! So even if a font
is only a screen bitmap font it should be printable.
Of course these fonts will not be as nice as postscript
fonts but that is too bad.
4. Proposal for new implementation
I propose the seperation of the font system into three
layers. From the bottom up these are
- The font installer. This is a seperate application
that takes care of finding all the fonts and taking
care of configuration of the font system.
The font installer will write all the configuration data
it finds into a form suitable for reading by the GNUstep
system. This is will be an extended version of the
font cacher as it is used now.
Besides just finding the fonts it will calculate all
redundant font data that the GNUstep system needs.
This includes
- The AFM font metrics
- The font traits
- The mapping from font names + size/matrix --> font + renderer
All the font configurationis parsed here. (Except maybe
very specific backend configuration issues).
- The backend.
- Reads data from the font installer
- Limits data to the fonts the backend supports
- Initialize frontend fonts with the AFM + traits data
- Manages Font --> screen font mapping
- Renders font on screen
- The frontend.
- Manages all font metric data. Such as calculation
of width etcetera.
- Manages all user interaction.
GUI | NSFont GSFontInfo
| ----- ----------
| Object the Provides common
| GUI lib sees logic, mostly derived
| from the AFM file info.
| The AFM file info is
| derived from the backend.
|
|
|
Backend | General GSFontInfoChild
| ------- ---------------
| Reads data from Specializes GSFontInfo
| font installer provide mapping between
| printer <--> screen font
|
|
Font | Finds all fonts on the system.
Installer| Parses configuration. Creates AFM
| info from fonts. precomputes
| stores it in a dictionary.
5. Questions
5.1 Non-technical questions
- What is a minimal set of fonts for GNUstep? I would
say Helvetica and one fixed width font.
- Do we include these fonts with GNUstep or let we
GNUstep automatically map them to system fonts?
5.2 Screen vs. printer fonts
- From the Openstep specification I cannot determine
if the (class) methods that create a font object
create a screen font or a printer font. But perhaps this does not
matter and takes the -set method care of selecting the
screen font when it is displayed in on the screen
and a printer font when we are printing.
This seems the logical choice.
- Is it required that the screen font and the printer font
have the same font metrics? I can see two approaches here
- You require the metrics to be the same. This is
the easiest, way out, but also makes sure that the representation
on the display is not acceptable from a esthetical viewpoint
(My opinion only)
- You allow a deviation between the screen font and
the printer font. If you still want to keep a reasonable
WYSIWYG feature the string drawing routines should
composate for the deviations by resizing the space between
words. This seems very tricky, I do not know enough
about the drawing of text yet to know if this is
easy, hard, very hard or impossible.