Using fonts with CFImage

One of the more useful bits of ColdFusion (version 8 and above) is the ability to dynamically write text as an image. As you can imagine, there are nearly endless uses for this. However, one of the more curious things is that it is not that easy to determine which fonts are available for you to use on the system on the fly. You can do it in the Administrative Console, but not programatically. . Worse, if you specify either a non-existent font or one that is not usable, ColdFusion throws a really ugly error. In the Pencilneck CMS, we have a number of bits of code that allow both ourselves & our users to generate images from text on the fly, and so it has become important to know what fonts are available. To that end, I wrote a pair of scripts today that now handle this for me, which I’m going to share below. One important note: In order for this script to work, you must have administrative access to ColdFusion, as it uses one of the Admin API components. The first script simply loads a list of all the valid, usable fontnames in a list (my apologies in advance for this not being properly indented. I’ve not yet found a good way of writing code with WordPress):

<cffunction name=”getServerFonts” access=”public” output=”false” returntype=”string”>
<cfargument name=”loginPW” type=”string” required=”true” />
<cfset var x = structNew() />
<cfscript>
adminObj = createObject(“component”,”cfide.adminapi.administrator”);
// this shoud be the CF admin log in
adminObj.login(arguments.loginPW);
myAdmin = createObject(“component”,”cfide.adminapi.runtime”);
x.fontList = myAdmin.getfonts();
</cfscript>
<cfset x.basicFontList = “” />
<cfloop collection=”#x.fontlist.systemfonts#” item=”x.i”>
<cfloop collection=”#x.fontlist.systemfonts[x.i]#” item=”x.j”>
<!— we disallow the “Adobe Built-in” fonts because CF can’t use them. This list is inclusive, not exclusive simply by my own preference —>
<cfif ListFindNoCase(“TRUETYPE,TRUETYPE-COLLECTION,OPENTYPE”,x.fontlist.systemFonts[x.i][x.j].fonttype)>
<cfset x.basicfontList =ListAppend(x.basicfontList,x.j) />
</cfif>
</cfloop>
</cfloop>

<cfloop collection=”#x.fontlist.userfonts#” item=”x.i”>
<cfloop collection=”#x.fontlist.userfonts[x.i]#” item=”x.j”>
<cfif ListFindNoCase(“TRUETYPE,TRUETYPE-COLLECTION,OPENTYPE”,x.fontlist.userFonts[x.i][x.j].fonttype)>
<cfset x.basicfontList =ListAppend(x.basicfontList,x.j) />
</cfif>
</cfloop>
</cfloop>

<cfreturn listSort(x.basicfontlist,”TextNoCase”) />
</cffunction>

So I like to run this script once on init, and load this list of fonts up into server scope so it’s available to all my applications. Once that exists, it becomes trivial to check for the existence of a font, which I do with the following script:

<cffunction name=”isSystemFont” output=”false” access=”public” returntype=”boolean”>
<cfargument name=”fontName” type=”string” required=”true” />
<cfset var x = structNew() />

<cfif NOT isDefined(‘server.fontList’)>
<!— do this in case the server.fontList hasn’t been initialized yet. If you load your fonts into a different scope, edit this —>
<cfset server.fontlist = getServerFonts() />
</cfif>
<cfif ListFindNoCase(server.fontList,arguments.fontName)>
<cfreturn true />
<cfelse>
<cfreturn false />
</cfif>
</cffunction>

And that’s it. I can now safely test to see if a font is available on a server or not, and then have conditionals by preference, etc. or whatnot. Hopefully, this’ll be useful for you too in your adventures in coding.

Minor site Tweaks

I’ve made some minor edits to the site:

  • The biggest change is the header: I’m now pulling in a random image to be the background for the heaader – these are all photos I’ve taken (with the exception of the “comrade”, who used to feature more prominently on this site, and is still my “icon” across virtually every social network I use).
  • Typekit: The site-title is now rendered using Typekit. I suspect which font I use will change over time – nothing stresses me out more than choosing appropriate typography, but for now, I’m using CarbonType by Vic Fieger. You’ll also see a little badge at bottom-right linking to a standarized colophon from them.
  • Less Clutter: I got rid of the “Stickers” in favour of an “Elsewhere”, listing where else you can find me, and did away with the flickr Badge, as I never did like the layout, so it’s a little cleaner down the right-hand-side. I may move to a two-column layout at some point, but this’ll do for now.
  • Colors: Gone is the blue, replaced with a grey, although. Not wholly satisfied with it, but it’ll do for now.

That’s it! Minor tweaks, but long overdue.

%d bloggers like this: