… without Java or authenticating against the CFIDE object!
I’ve recently been working on a pure ColdFusion / CFImage implementation to generate dynamic title images in specific fonts.
As part of the configuration of this particular code I needed to access the installed font list but the only method I could find documented required using CFIDE.adminapi.runtime which in turn requires that the code has the CFIDE admin username and password embedded.
Generally speaking I’d prefer to avoid this in production and so started to look at an alternative method of getting the font list. Whilst hacking about with ImageDrawText() my colleague noticed that, if you supply a bad font name (i.e. on that isn’t installed) the exception returns a list of available fonts. With a bit of hacky logic it’s possible to parse this list into a usable array:
[cf]
<!—
Use ImageDrawText exception to access the server’s font list and store in an array
—>
<cfset variables.debugTimer.start = getTickCount() />
<!— Setup a temporary image object. It doesn’t need to be very big —>
<cfset variables.tmpImage = ImageNew("", 1, 1, "rgb", ’000000′ ) />
<!— Use a font name we can guarantee is not going to be installed.
For ease I’m using random characters. In production you may wish
to consider using a hashed UUID —>
<cfset variables.imgAttr.font = "qwertyuiopasdfghjklzxcvbnm" />
<cftry>
<!— Try to write a single character on our temporary image.
As the font cannot be found this will throw an exception —>
<cfset ImageDrawText(variables.tmpImage, "a", 0, 0, variables.imgAttr) />
<!— Catch the exception to populate the CFCatch struct —>
<cfcatch type="any">
<!— We should now have a <br> separated list of supported fonts in the CFCatch struct —>
<cfset variables.tmpFontList = replace(cfcatch.FontList,"<br>","|","All")>
<!— Test to ensure the list has been populated correctly —>
<cfif variables.tmpFontList neq "" AND listLen(variables.tmpFontList,"|") gt 1>
<!— Convert the list to an array —>
<cfset variables.arrayFonts = listToArray(variables.tmpFontList,"|") />
<cfelse>
<!— The list hasn’t been populated correctly. Handle this as you wish —>
<cfabort />
</cfif>
</cfcatch>
</cftry>
<cfset variables.debugTimer.end = getTickCount() />
<cfset variables.debugTimer.total = variables.debugTimer.end – variables.debugTimer.start />
<cfdump var="#variables.arrayFonts#" label="ArrayFonts" expand="false" />
<cfdump var="#variables.debugTimer#" label="Timing Info in Milliseconds" expand="true" />
[/cf]
As I said – this is a hack! But if you need a quick and dirty way to get at your font list without CFIDE access or invoking Java classes then this will get the job done.