This is an old revision of the document!
A font system has been implemented in the git branch home/cparker/font_fun. This system was initially designed by Chad Parker. The initial set of fonts were converted for PCB by Erich Heinzle. With this system, the font of a design can be easily changed, and multiple fonts can be used in the same design. This system also reduces the need to store font data in saved design files, because a font name should be forever. If a font ever changes, it should be given a new name. So, saved designs can reference only the font name without having to worry about the font changing and a design being different when it is next opened.
To test the font system, check out the feature branch from git. Switch to the feature branch with
git checkout home/cparker/font_fun
reconfigure if necessary and build. Then, run pcb by executing the pcbtest.sh script in the src directory. This is important because it sets the font path so that pcb can load some of the included fonts.
All font settings can be viewed and edited from the Fonts tab in the preferences window.
There are three font related options that can be configured:
There are two fonts that can be configured:
The fonts can also be manipulated by executing Actions.
There are two font libraries:
Fonts can be easily changed using the Fonts tab in the preferences window:
Alternatively, all text in a design can have a font assigned by using the “Change All” button.
Note that these methods will only change the font of discrete text objects. Reference designators of components cannot presently have fonts assigned to them individually. However, the font of *all* reference designators can be changed together by setting the PCB Font to the desired font.
Previous versions of pcb would store the data of a single font in saved files as symbols. Alternatively, if the file did not contain symbols, perhaps because they were deleted, then pcb would load the default font instead. This feature branch will still play nicely with these scenarios.
If you load an existing design that has symbols stored in the design, the symbols will be converted into an embedded font (Font 0), all the text objects in the design will use that font, and that font will be set as the system font. If the design does not have symbols stored in it, then the text objects will be assigned the system font. So, if you've changed the system font then the text objects will not look exactly as they did when you saved them. However, If you load a design and don't like the font the text ends up in, it's easy to change the font.
The font system is implemented using a few data structures and several actions.
The font data structure is called FontType and is defined in global.h as follows:
typedef struct { char * Name; char * SourceFile; Coord MaxHeight; /*!< Maximum cell width. */ Coord MaxWidth; /*!< Maximum cell height. */ BoxType DefaultSymbol; /*!< The default symbol is a filled box. */ SymbolType Symbol[MAX_FONTPOSITION + 1]; int nSymbols; } FontType;
The MaxHeight and MaxWidth parameters are set by the SetFontInfo function that's been relocated into font.c. This structure has updated to include two new fields for the name of the font and the source file of the font.
The two font libraries (system and embedded) are both implemented as GLib GSLists. Each list element points to a FontType structure. The choice of a GSList was made because its a simple structure, and at the moment I don't anticipate there being a vast database of fonts to choose from, so searching through a list ought not to take all that long. GLib includes many functions for working with GSLists, and these are used for managing and accessing the list items.
Searching through the library for a font is done by using the FindFontInLibrary function. This function iterates through the list once comparing the name of the font to the provided reference string. If a match is not found, the list is searched through again comparing the name of the source file. If it's still not found then a null is returned.
A second function, FindFont, is available for searching. This function searches first through the embedded library, and if the font is not found, it will then search through the system library. This way, the embedded library always has precedence. So, if a customized version of a font is stored in the pcb file and there is a system font with the same name, the embedded font will be used. The assumption is that if the font was explicitly stored in the file, it was done so to ensure that it was used.
The format for font files is basically the same as the format for symbols in complete pcb files, with one new keyword: Font. The argument of the Font keyword is the name of the font. Following the Font keyword a set of symbols using the existing pcb format are wrapped inside of normal parenthesis.
Font("Default") ( Symbol(' ' 18) ( ) Symbol('!' 12) ( SymbolLine(0 35 0 40 8) SymbolLine(0 0 0 25 8) ) ... ) # end font
The “# end font” is just for reference and is not required.
A font file can have one or more fonts defined in succession.
A single addition to the file format has been implemented. That's the Font directive that was described above. That directive can have two meanings. Fonts can be embedded in regular pcb files using the same syntax as above. The only caveat is that the font must be defined early in the file, between the styles and the layout data.
The Font directive can also be included without symbols. If it appears this way, then the argument is considered to be the PCB Default Font. This font is made the current font and is used for all reference designators and for any text objects that are not explicitly assigned a font.
The ChangeFont action can has two forms that can be invoked from the pcb command entry, a single argument version and a two argument version.
Syntax:
ChangeFont(fontname)
ChangeFont
action changes the current system font to the font specified by fontname
.ChangeFont([All|Selected|Object|System|PCB], fontname)
ChangeFont
action changes the font of the specified item to the font specified by fontname
.The first argument to the second form has the following effects:
All
Selected
Object
System
PCB
All
, Selected
, and Object
action will not change the font of dynamically generated text such as pin names/numbers or text that cannot be assigned a specific font, such as reference designators.
The Load Font Action is primarily an interface to the LoadFont function with the argument being the name of the file containing the font(s) to load. Calling this action with the argument All
will instead call the ScanFontPaths function which searches the font-path for files with the extension .pcb_font
and tries to load them as fonts.
Fonts can only be deliberately loaded to the system font library, so prior to reading the specified file, the system library is checked for a font that came from a file with the same name. If it is present, then it does not reload the font. So, if you've changed a font and want to update it without closing pcb, you must first use the Unload Font Action to unload the font. Then you can reload it. (Note that the Unload Font Action will not allow you to unload a font that is currently being used in the design.)
A note on the LoadFont function: the ParseFont function is still used, however, the details of how fonts are parsed in parse_y.y have been modified to create fonts in the appropriate library. After ParseFont reads the file and loads the data, the new font is appended to the end of the GSList that is the library. LoadFont exploits this to get the font pointer and set the name of the source file in the data structure. LoadFont then explicitly sorts the library to put the entry in alphabetical order.
These are tasks and ideas related to the font subsystem that still need to be done, could be done, or are in progress: