-
Notifications
You must be signed in to change notification settings - Fork 309
Compiling FreeType
-
Any version of linux should work, although I have only tested this on 32-bit lubuntu.
-
From Windows, use a pre-built VMware Player for 32-bit lubuntu. I would not recommend trying to compile freetype directly from Windows. There are too many unix-y things about the freetype compilation process that emscripten will likely have trouble with.
-
Update linux with the required build dependencies:
$ sudo apt-get install git $ sudo apt-get install default-jre $ sudo apt-get install cmake $ sudo apt-get install g++
-
Goto the node.js web site and download, build, and install node.
-
Download and unpack emscripten. I used emsdk-portable for linux and installed to
~/emsdk
. -
Follow the install instructions on the emsdk page. At the time of writing:
$ cd ~/emsdk $ ./emsdk update $ ./emsdk install latest $ # Get a cup of coffee or two.... $ ./emsdk activate latest $ . emsdk_env.sh
-
Goto the freetype web site and download and unpack the latest freetype source. I installed to
~/freetype-2.5.5
. -
cd ~/freetype-2.5.5
-
Customize modules.cfg. For bwip-js, I commented out everything that was not needed to render OpenType and TrueType fonts. This was done to make the resulting JavaScript module as small as possible.
Comment lines beginning
#MRW
were added by the author. -
Next, you must empty the file
builds/exports.mk
:# # FreeType 2 exports sub-Makefile # # EOF
-
Emscripten maintains tables of function pointers which are indexed both by return type and their parameter types. The FreeType hinting code casts functions returning
int
to functions returningvoid
, which causes a function-not-found exception when working with certain fonts. You must make the following change tosrc/autofit/aftypes.h
:typedef int (*AF_WritingSystem_ApplyHintsFunc)( AF_GlyphHints hints, FT_Outline* outline, AF_StyleMetrics metrics );
The
void
return type must be changed toint
as shown above. -
By default, FreeType links in
zlib
andgzip
to handle fonts compressed for the X-Windows system. Those dependencies cause link-time issues for Emscripten. Disable by commenting out the following directives ininclude/config/ftoption.h
:/* #define FT_CONFIG_OPTION_USE_LZW */ /* #define FT_CONFIG_OPTION_USE_ZLIB */
-
There are the glyph metrics plus the bitmap that we need to move between the freetype module and bwip-js. Due to emscripten's architecture, this is not straightforward. The best approach I have found is to create a
main.c
which initializes the freetype library and defines functions we can call directly from JavaScript. -
From bwip.js, this is what the freetype interface looks like:
BWIPJS.ft_lookup = Module.cwrap("find_font", 'number', ['string']); BWIPJS.ft_bitmap = Module.cwrap("get_bitmap", 'number', ['number','number','number']); BWIPJS.ft_width = Module.cwrap("get_width", 'number', []); BWIPJS.ft_height = Module.cwrap("get_height", 'number', []); BWIPJS.ft_left = Module.cwrap("get_left", 'number', []); BWIPJS.ft_top = Module.cwrap("get_top", 'number', []); BWIPJS.ft_advance= Module.cwrap("get_advance", 'number', []);
-
Separate functions are provided to get the glyph bitmap (which initializes the glyph slot struct with its corresponding metrics) and each glyph metric.
-
Another issue to consider is how to include the OCR font files so freetype has access to them. emscripten provides two options, either embedding the files in the compiled JavaScript, or demand loading them using XHR. For this initial release, I chose to embed them.
-
Build freetype with emscripten and compile in main.c:
$ emconfigure ./configure $ emmake make $ emcc -I ./include -o main.o main.c $ emcc -O3 --embed-file OCRA.otf --embed-file OCRB.otf -s NO_EXIT_RUNTIME=1 \ -s EXPORTED_FUNCTIONS='["_main","_load_font","_find_font","_get_bitmap",\ "_get_left","_get_top","_get_width","_get_height","_get_pitch","_get_advance"]' \ main.o objs/.libs/libfreetype.so -o freetype.js
-
You should now have two files in your working directory:
freetype.js freetype.js.mem
-
To use in a browser, include only
freetype.js
in a <script> tag. The mem-file will be demand loaded. The test filefreetype.html
shows how to use the library:The files
freetype.js
andfreetype.js.mem
are also available in the repository.