Subject: [PATCH 5/5] Makefile: now support other common export formats (v3)

From: Jan Pokorný <[email-masked]>
Date: Mon, 20 Feb 2012 15:39:46 +0100

Based on the previous patch, we create a generalization of how was
"ttf" target handled to support exporting also to other common
formats.  We add "4web" target covering common formats used on
the web (HTML/CSS:font-face): TTF, WOFF, SVG, EOT.
It is easy to add other formats if needed and provided that
such format is supported by FontForge.

Update v2
---------

EOT is not supported natively by FontForge, so in fact, another tool
is needed, either will serve the purpose:
    1. mkeot from eot-utils (http://www.w3.org/Tools/eot-utils/)
    2. ttf2eot (http://code.google.com/p/ttf2eot/)

Unfortunately, these are not commonly packaged so they have to be
compiled from source.  This is quite straightforward, only in case 2.,
extra header file has to be imported, see [1].

The Makefile supports both these convertors.  I made some comparison
of the two and the output is similar, although 2. seems to be doing font
subsetting and supports setting the URL prefixes where the font is
intended to be used -- this can be explictly requested using:

    make eot MKEOT_URLS="URL1 URL2 ..."

Because 1. is also under the wings of authoritative organization (W3C),
I arranged it as prioritized choice with the fallback to 2. if mkeot
is not found on the PATH (if even this is missing, the eot target fails).

If official distribution of web fonts incl. EOT is ever to be made,
I think it is important to mark (in the form of a comment in Makefile)
the "canonical" converter.  I anticipated it is 1. as well, but it can be
changed anytime (preferrably also fallback order is changed then).

In scripts/fontexport.pe, printing newline is removed.

Update v3
---------

Use "libre roots" by default for EOT as it seems that 1+ root is needed
for MSIE 8+ and these are as neutral as possible (see also test page
[2]).

Also, make should be more parallel-run-friendly now regarding creation
of export dir.

[1] http://code.google.com/p/ttf2eot/issues/attachmentText?id=22&aid=220001000&name=cstddef.patch
[2] http://jpokorny.fedorapeople.org/font-test/liberation-sans-italic.html

Signed-off-by: Jan Pokorný <[email-masked]>
---
 source/Makefile              |   60 ++++++++++++++++++++++++++++++++++++-----
 source/scripts/fontexport.pe |    1 -
 2 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/source/Makefile b/source/Makefile
index 995443b..520d892 100644
--- a/source/Makefile
+++ b/source/Makefile
@@ -1,7 +1,30 @@
+# common targets:
+# <no target>, build, ttf-dir: create dedicated dir with TTF files
+# ttf:                         create export dir with TTF files, track changes
+# 4web:                        dtto for TTF, WOFF, SVG, and EOT
+
 FONTFORGE    = fontforge
 FONTLINT     = fontlint
 
-SCRIPTS      = scripts/sfd2ttf.pe scripts/ttf2sfd.pe scripts/fontexport.pe
+# TTF->EOT converters in fallback order
+# the first one is canonical choice used in the release process
+MKEOT        = mkeot
+# URLs to be used for root string within EOT file;
+# defaults to "libre roots" that allow usage on any common web page
+MKEOT_URLS   = http:// https:// file://
+TTF2EOT      = ttf2eot
+ifneq ($(strip $(shell which $(MKEOT) 2>/dev/null)),)
+    make_eot = $(MKEOT) $(1) $(MKEOT_URLS) > $(2)
+else
+    ifneq ($(strip $(shell which $(TTF2EOT) 2>/dev/null)),)
+        make_eot = $(TTF2EOT) $(1) > $(2)
+    else
+        make_eot = $(error No tool for TTF->EOT conversion: $(MKEOT), $(TTF2EOT))
+    endif
+endif
+
+EXPORTSCRIPT = scripts/fontexport.pe
+SCRIPTS      = $(EXPORTSCRIPT) scripts/sfd2ttf.pe scripts/ttf2sfd.pe
 MISCFILES    = AUTHORS ChangeLog COPYING License.txt README TODO
 SRCDIR       = src
 EXPORTDIR    = export
@@ -30,16 +53,37 @@ $(EXPORTDIR):
 # TrueType/OpenType Font, general usage
 # - ttf cares about source file changes, using shared EXPORTDIR
 # - ttf-dir should be a bit more efficient, creating dedicated dir for TTF
-ttf: $(EXPORTDIR) $(TTFFILES)
+FORMATS = ttf
 ttf-dir:: $(SFDFILES)
-	$(FONTFORGE) -script ./scripts/fontexport.pe -ttf $^
+	$(FONTFORGE) -script $(EXPORTSCRIPT) -ttf $^
 	mkdir -p $(DISTPREFIX_TTF)
 	mv $(addsuffix .ttf,$(basename $^)) $(DISTPREFIX_TTF)
 
-# single file export (primarily used by other targets)
-$(EXPORTDIR)/%.ttf:: $(SRCDIR)/%.sfd
-	$(FONTFORGE) -script ./scripts/fontexport.pe -$(lastword $(subst ., ,$@)) $<
-	mv $(SRCDIR)/$(notdir $@) $(EXPORTDIR)
+# web sites usage
+# Web Open Font Format (WOFF); for all modern browsers (W3C recommendation)
+FORMATS += woff
+# SVG Font; only for WebKit and Presto based browsers (Firefox "avoids" it)
+FORMATS += svg
+# Embedded OpenType (EOT); MSIE only [extra recipe, FontForge can't create EOT]
+FORMATS += eot
+eot:: $(addprefix $(EXPORTDIR)/$(NAME), $(VARIANTS:=.eot))
+	@echo
+$(EXPORTDIR)/%.eot: $(EXPORTDIR)/%.ttf | $(EXPORTDIR)
+	$(call make_eot,$<,$@)
+4web: ttf woff svg eot
+
+# XXX: declare other formats here if needed (TeX, etc.)
+
+# default for formats without extra recipes defined above (e.g., not "eot"):
+# summary per-format target + single file export for these declared formats
+define FORMAT_template =
+$(1):: $$(addprefix $$(EXPORTDIR)/$$(NAME), $$(VARIANTS:=.$(1)))
+	@echo
+$$(EXPORTDIR)/%.$(1):: $$(SRCDIR)/%.sfd | $$(EXPORTDIR)
+	$$(FONTFORGE) -script $$(EXPORTSCRIPT) -$$(lastword $$(subst ., ,$$@)) $$< 2>/dev/null
+	mv $$(SRCDIR)/$$(notdir $$@) $$(EXPORTDIR)
+endef
+$(foreach format,$(FORMATS),$(eval $(call FORMAT_template,$(format))))
 
 dist: clean-dist dist-sfd dist-ttf
 dist-src: dist-sfd
@@ -74,4 +118,4 @@ clean: clean-dist
 clean-dist:
 	rm -f -- *.tar.gz *.zip
 
-.PHONY: all build ttf-dir ttf dist dist-src dist-sfd dist-ttf check clean clean-dist
+.PHONY: all build ttf-dir ttf dist dist-src dist-sfd dist-ttf 4web $(FORMATS) check clean clean-dist
diff --git a/source/scripts/fontexport.pe b/source/scripts/fontexport.pe
index 031cf08..343f808 100644
--- a/source/scripts/fontexport.pe
+++ b/source/scripts/fontexport.pe
@@ -17,6 +17,5 @@ while ($argc > 1)
     Open($1)
     Generate($1:r + "." + format, "", 0x800)
     Close()
-    Print("")
     shift
 endloop
-- 
1.7.3.4