Homebrew, open source, repurposed, hacked, software defined, open hardware

Tuesday 23 September 2014

geda PCB font utilities and options including hebrew, greek, cyrillic and unicode CJK glyphs

I have converted some of the free Hershey fonts for use with the free and open source geda PCB design software, after starting with Hershey Sans 1 stroke to provide a more contoured default font.

In the process I wrote a small piece of C code pcbFontTool.c to simplify processing of pstoedit outputs and conversion into PCB Designer compatible font symbols.

Having streamlined the process somewhat, I figured why not do some of
the other fonts, so, PCB users now have the choice of:

Hershey Sans 1 stroke
Hershey German Gothic
Hershey Italian Gothic
Hershey English Gothic
Hershey Cyrillic - with keyboard mapping to be determined by user
Hershey Greek - with keyboard mapping to be determined by user

and the usual default_font

I have uploaded the fonts, the pcbFontTool utility, and instructions for those wishing to convert other fonts, to an ftp server

The license for pcbFontTool.c is GPL v2  or at the user's option GPL v3. The code could be improved but it does the job quite effectively.

These fonts are a simple drop in replacement for default_font, which at this stage lives in /geda/pcb/src
Until we have a mechanism for selecting fonts in PCB, this is what users will have to do.

I strongly recommend that anyone using geda PCB install git, clone the git repository, and build a local version of PCB so that they are running the latest version of PCB.

The pcbFontTool.c utility is standalone, only uses stdio, and has an attached README.txt

users.on.net/~esh/geda/pcb/src/fonts/README.txt

The gothic and sans fonts use the normal ASCII/US keyboard mapping.

The cyrillic font uses a keyboard mapping based on the Hershey fonts as distributed.
There are four or more types of cyrillic keyboard mapping in use, so a glyph table has been included to assist anyone trying to use it.

Likewise for the Greek font, a glyph table is included and PCB users will need to determine how they want to map the symbol to their keyboard. Users will have to add their own accents to the Greek vowels. There is a glyph table to show the Greek mapping as well.
 
The issue of CJK (Chinese, Japanese and Korean) glyphs was looked at next.

The GNU unifont bdf is available from unifoundry, which has released the GNU unifont as a free and open source font for use in FOSS.

http://unifoundry.com/pub/unifont-7.0.03/font-builds/unifont-7.0.03.bdf.gz

hosted by:

http://unifoundry.com/unifont.html

The reason that the GNU unifont has been made available in bdf format is because the bdf format is commonly used by X windows systems

http://en.wikipedia.org/wiki/Glyph_Bitmap_Distribution_Format

The bdf font file is a series of consecutive symbol definitions of the form:

STARTCHAR U+004E
ENCODING 78
SWIDTH 500 0
DWIDTH 8 0
BBX 8 16 0 -2
BITMAP
00
00
00
00
42
62
62
52
52
4A
4A
46
46
42
00
00
ENDCHAR

Chinese, Japanese and Korean (CJK) glyph rendering is not trivial and the approach taken by others has been to use bitmapped glyphs for resolutions below 16x16 pixels, and vector font formats for larger sizes.

The GNU unifont project has an essentially complete set of CJK glyphs in 11x11, 12x12, 13x13, 14x14, 15x15 and 16x16 pixel bitmap formats as produced and released as a free and open CJK font by Firefly around 2005.

The GNU unifont project includes around 20,000 CJK symbols that can now be used in gEDA PCB if required.

The batch converted set of CJK symbols are based on the 16x16 bitmapped Firefly CJK font set and have had contiguous pixels vertically, horizontally and diagonally converted into SymbolLine[] strokes, and orphan pixels if any, are rendered as a dot. A default stroke width of 800 has been used.

The smaller 11x11, 12x12 13x13, 14x14, 15x15 bitmapped CJK glyphs also could be easily converted if necessary, but they may lack the fidelity of the 16x16 glyphs which can be scaled anyway within PCB, so I have not bothered to convert the lower resolution bitmaps at this stage.

I have finished off the pcbGlyphTool code I used to batch convert Chinese/Japanese/Korean (CJK) Firefly bitmap glyphs to pcb symbols

This more polished version of the code fixes a boundary condition affecting 2 or 3 glyphs in the Firefly CJK 16x16 font set with pixels along edges.

The pcbGlyphTool utility:

1) acquires a valid BDF symbol definition via stdin
2) extracts the glyph label, glyph height, glyph width, display width, and the bitmap nibbles
2.1) optionally exports an xbm bitmap
2.2) optionally exports a "Dot matrix" PCB symbol rendition of the glyph using SymbolLine strokes to depict dots
3) stores the nibbles for each line in the glyph as a single integer
4) creates arrays in which each pixel is depicted as an integer
5) steps through the single integer representation of the rows and scores each pixel, putting the score into the integer per pixel row array
6) exports consecutive rows of pixels as SymbolLine strokes
7) steps through each column of scored pixels and does further scoring of each pixel, putting the score into the integer per pixel column array
8) exports consecutive columns of pixels as a SymbolLine strokes
8.1) optionally exports a symbol without diagonal row detection and conversion to strokes
9) creates left and right skewed arrays of the final pixel scores after column and row export
10) steps through the single integer representation of the right skewed array columns and detects diagonals, exports SymbolLine strokes
11) steps through the single integer representation of the left skewed array columns and detects diagonals, exports SymbolLine strokes
12) identifies any left over/orphan pixels and exports a SymbolLine stroke to depict a "dot"
13) exports a complete symbol with vertical, horizontal, and diagonal strokes
14) looks for another BDF symbol via stdin
This produces output containing a series of geda PCB symbol definitions for each glyph, and is what is in the gz file linked to above.

Until we have a mechanism for seamlessly adding unicode symbols or rendering ttf fonts, users needing glyphs can search the gzipped archive and cut and paste their needed symbol, and relabel it to assign it to an unused ascii character.

The utility compiles easily with gcc and one need only feed it with a bdf symbol definition or a stream of bdf symbol definitions to produce PCB symbols for insertion into a PCB layout, with suitable re-labeling to comply with the current limitations imposed by the implementation of "Symbol" which only copes with ~ 127 symbols.

i.e.

cat mydesiredglyph.bdf | ./pcbGlyphTool > NewSymbolForPCB.pcb

./pcbGlyphTool -h

will list other options, including -d "dot matrix rendition", -o "omitting" conversion of diagonals into strokes, -v "verbose" mode, and -x generate an xbm mode.

It should convert any bdf formatted bitmap up to 16x16 pixels into SymbolLine strokes replacing contiguous pixels in horizontal, vertical or diagonal directions, and it will render remaining "orphan pixels" as a dot.

Users requiring a few glyphs can now include them and map them to spare ASCII symbols until there is a way to more easily include unicode symbols, i.e.

Symbol['6' 1200]
#gEDA PCB compatible symbol with drawn elements depicting uni9ED6
#Symbol['uni9ED6' 1200]
(  etc...
)
I expected to walk away from the computer for at least a few minutes to convert the 20,000+ CJK bdf archive but it was done in seconds, meaning that on the fly importing of single CJK glyph bdf definitions from the freely downloadable GNU unifont bdf could in theory be done from within PCB if a suitable menu option were available.

The entire set of batch converted 16x16 bitmapped CJK glyphs as an uncompressed text file weighs in at around 20MB, but compressed is only around 1.5MB

I hope this is useful to anyone desperately in need of some functional CJK glyphs before gEDA PCB supports either an integrated conversion process like this or TTF support.

I cannot vouch for the rendering of all of the glyphs, as I do not read Chinese, Japanese or Korean, I haven't had the chance to review them all, and the heuristics may have joined the occasional diagonally adjacent pixels which should remain unjoined.

The symbol archive is released under GPL2 or at your option, a later version, can be freely distributed, and the usual font exception applies.

I would make the observation that this approach to glyph rendering makes for quite a compact symbol definition. My initial efforts involving conversion of curved paths over the glyphs produced symbol definitions 3-4 times the overall size, with implications for final PCB file size. It would be interesting to see how much bigger or smaller gerbers might end up being if text is rendered as polygons derived from TTF fonts.

As a bonus, the same bdf glyph conversion tool pcbGlyphTool.c was able to generate a Hebrew font from the GNU unifont 16x16 pixel bdf file, and this is located at

http://users.on.net/~esh/geda/pcb/src/fonts/UnifontDerivedHebrew_Font

and a glyph table is included so that users can decide how to map them to their keyboard

http://users.on.net/~esh/geda/pcb/src/fonts/gEDA-PCB-Unifont-Hebrew.pcb

The hebrew font could no doubt be improved aesthetically, but it is a start at least.

Anyway, someone may find the utilities or their subroutines useful.

I make no claims as to my code's elegance or fitness for purpose; the production of the code was a learning exercise and if I were to do it again I would of course do it differently...