Wednesday Contest Solution (pt. 2)

And here's the extra credit solution:

<cfif NOT isDefined("attributes")>
  <cfset attributes = structNew() />
  <cfset structAppend(attributes, form, false) />
  <cfset structAppend(attributes, url, false) />
</cfif>
<cfparam name="attributes.width" default="100" />
<cfparam name="attributes.height" default="100" />
<cfparam name="attributes.backgroundColor" default="f7f7f7" />
<cfparam name="attributes.borderColor" default="cccccc" />
<cfparam name="attributes.textColor" default="990000" />
<cfparam name="attributes.text" default="Hello!" />
<cfparam name="attributes.textSize" default="16" />
<cfparam name="attributes.textStyle" default="bolditalic" />
<cfparam name="attributes.textFont" default="courier new" />

<cfset fontArgs = structNew() />
<cfif structKeyExists(attributes, "textSize") AND isNumeric(attributes.textSize)>
  <cfset fontArgs["size"] = attributes.textSize />
</cfif>
<cfif structKeyExists(attributes, "textStyle") AND len(trim(attributes.textStyle)) GT 0>
  <cfset fontArgs["style"] = attributes.textStyle />
</cfif>
<cfif structKeyExists(attributes, "textFont") AND len(trim(attributes.textFont)) GT 0>
  <cfset fontArgs["font"] = attributes.textFont />
</cfif>

<cfset image = imageNew("", attributes.width - 2, attributes.height - 2, "rgb", attributes.backgroundColor) />
<cfset imageAddBorder(image, 1, attributes.borderColor) />

<cfset imageSetAntialiasing(image, "on") />
<cfset imageSetDrawingColor(image, attributes.textColor) />

<cfset graphics = imageGetBufferedImage(image).getGraphics() />
<cfset originalFont = graphics.getFont() />

<!--- default the fontArgs struct based on the default font --->
<cfif NOT structKeyExists(fontArgs, "font")>
  <cfset fontArgs.font = originalFont.getFontName() />
</cfif>
<cfif NOT structKeyExists(fontArgs, "size")>
  <cfset fontArgs.size = "" & originalFont.getSize() />
</cfif>
<cfif NOT structKeyExists(fontArgs, "style")>
  <cfif originalFont.isBold() AND originalFont.isItalic()>
    <cfset fontArgs.style = "bolditalic" />
  <cfelseif originalFont.isBold()>
    <cfset fontArgs.style = "bold" />
  <cfelseif originalFont.isItalic()>
    <cfset fontArgs.style = "italic" />
  <cfelse>
    <cfset fontArgs.style = "plain" />
  </cfif>
</cfif>

<!--- create the new font --->
<cfset font = createObject("java", "java.awt.Font") />
<cfif fontArgs.style EQ "bolditalic">
  <cfset style = bitOr(font.BOLD, font.ITALIC) />
<cfelseif fontArgs.style EQ "bold">
  <cfset style = font.BOLD />
<cfelseif fontArgs.style EQ "italic">
  <cfset style = font.ITALIC />
<cfelse>
  <cfset style = font.PLAIN />
</cfif>
<cfset newFont = font.init(fontArgs.font, javaCast("int", style), javaCast("int", fontArgs.size)) />

<!--- get the FontMetrics, this time for the new font --->
<cfset bounds = graphics.getFontMetrics(newFont).getStringBounds(attributes.text, graphics) />

<!--- draw it --->
<cfset imageDrawText(
  image,
  attributes.text,
  (attributes.width - bounds.getWidth()) / 2,
  (attributes.height + bounds.getHeight()) / 2,
  fontArgs
) />

<cfimage action="writeToBrowser"
  source="#image#" />

The implementation is fairly generic, though it contains no error handling, so it's still possible for fatal errors to crop up (particularly with font names). Quite a lot of work for some simple centered text.

Leave a Reply

You must escape tags within your comment. Use &lt; for < and &gt; for >.