<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Jim Clark - Blogs at Near Infinity</title>


        <link>http://www.nearinfinity.com/blogs/</link>
        <description>Employee Blogs</description>
        <language>en</language>
        <copyright>Copyright 2010</copyright>
        <lastBuildDate>Mon, 30 Apr 2007 22:44:39 -0500</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>Introduction to PDF::TechBook</title>
            <description><![CDATA[<p>
Recently I had an interest in producing PDF documents using Ruby on Rails.&nbsp;
A quick Google search brought me to a Ruby PDF library called
<a href="http://ruby-pdf.rubyforge.org/pdf-writer/" title="PDF::Writer for Ruby">PDF::Writer
for Ruby</a> written by
<a href="http://www.halostatue.ca/" title="Austin Ziegler">Austin
Ziegler</a>.&nbsp; As far as I can tell from the online manual PDF::Writer is a
fairly robust library.&nbsp; The manual was well written and
generated by PDF::Writer itself, very impressive.&nbsp; By reading Austin's
introductory
<a href="http://www.artima.com/rubycs/articles/pdf_writer.html" title="Artima article">PDF::Writer
article</a> I was able to get up and running quickly.&nbsp; The article
demonstrates creating text, tables, drawings and inserting images.&nbsp;
However, I didn't need to do anything fancy like create charts or drawings (see
the PACMAN example). &nbsp; All I wanted was some basic header, text and code
styling.&nbsp; Out of the box PDF::Writer allows you to do these sort of things
but it requires some additional work on your part.&nbsp; PDF::Writer gives you
the primitives to work with to create whatever you want, but I didn't have the
time to go through the effort to create my own styling from scratch.&nbsp;
Fortunately, Austin extended PDF::Writer to create PDF::TechBook.&nbsp;
TechBook gives you the ability to mark up and style your content that can then
be used to generate a PDF document.&nbsp; This is a brief introduction to
TechBook.
</p>

<p>
The TechBook class extends PDF::Writer and is an interpreter that interprets a lightweight markup language.&nbsp; You
feed the TechBook class a string or a file that contains content and TechBook
markup to generate a PDF document.&nbsp; TechBook markup provides styling for
basic headings, preformatted blocks, code sections, columns, table of contents,
bulleted lists and a few other items.&nbsp; I equate this to
something like an HTML-lite or textile for PDFs.&nbsp; The markup
uses directives to indicate the start and end of a block of text.&nbsp; Some
directives are line oriented like headers that only require a start
directive.&nbsp; Other directives can span multiple lines like bulleted
lists.&nbsp; We'll start with a basic example.&nbsp;
</p>

<p>
Headers, similar to the &lt;H1-5&gt; tags in HTML, are supported up to five
headers by using the somewhat awkward format <code>#&lt;heading-text&gt;</code>, e.g.
</p><pre>    1&lt;Level 1&gt;
    2&lt;Level 2&gt;
    3&lt;Level 3&gt;
    4&lt;Level 4&gt;
</pre>
produces...<br /><br />
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="headings.JPG" src="http://www.nearinfinity.com/blogs/headings.JPG" class="mt-image-none" style="" height="112" width="692" /></span><br /><br />

With TechBook you can create bulleted lists using "discs" or standard bullets.&nbsp;
Here's an example showing how to create a bulleted list using the disc bullets.&nbsp; (To create standard bullets replace "disc" with "bullet")
<pre>    .blist disc
    Line item 1 with disc
    .endblist
    .blist disc
    Line item 2 with disc
    .endblist
    .blist disc
    Line item 3 with disc
    .endblist
</pre>
produces...<br /><br />
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="disc.JPG" src="http://www.nearinfinity.com/blogs/disc.JPG" class="mt-image-none" style="" height="71" width="190" /></span>


<p>
In addition to headings and lists, TechBook allows you to preformat text and identify code sections.&nbsp;&nbsp; E.g.
    </p><pre>    .pre
           Pre line 1
           Pre line 2
    .endpre
    </pre>

produces...<br /><br />
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="pre.JPG" src="http://www.nearinfinity.com/blogs/pre.JPG" class="mt-image-none" style="" height="51" width="115" /></span>&nbsp;<br /><br />
and
    <pre>    .code
    pdf = PDF::Writer.new
    pdf.select_font "Times-Roman"
    pdf.text "Hello Ruby", :font =&gt;14, :justification =&gt; :left
    pdf.save_as("e:/hello_ruby.pdf")
    .endcode
    </pre>

produces...<br /><br />
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="code.jpg" src="http://www.nearinfinity.com/blogs/code.jpg" class="mt-image-none" style="" height="73" width="524" /></span>&nbsp;<br /><br />
After you've created your content using the TechBook markup, it's easy to create a new instance of the PDF::TechBook class
and produce the PDF file.  The following is an example, where "my_content" is your marked-up content<br /><br />
    <pre>    pdf = PDF::TechBook.new
    pdf.select_font "Times-Roman"
    pdf.techbook_parse <span style="color: blue;">my_content</span>
    pdf.save_as("c:/temp/hello_ruby.pdf")
    </pre>


<p>
Download a sample program&nbsp;</p><span class="mt-enclosure mt-enclosure-file" style="display: inline;"><a href="http://www.nearinfinity.com/blogs/my_pdf_writer.rb">my_pdf_writer.rb</a></span><p>
</p>

<p>There are other features supported by TechBook such as table of contents and the eval directive, but hopefully this
    will give you a start to using TechBook.  If you view the raw version of the PDF::Writer manual that comes with gem you can get a good idea of
    what you can accomplish with PDF::Writer.  <br /><br />
    I'm interested in other solutions. Leave me a comment if you know of other ways and/or better ways to create PDF documents
    using Ruby or have additional tips using PDF::Writer.
</p><div><br /></div><div><br /></div><div><br /></div><div><br /></div>]]></description>
            <link>http://www.nearinfinity.com/blogs/jim_clark/introduction_to_pdf_techbook.html</link>
            <guid>http://www.nearinfinity.com/blogs/jim_clark/introduction_to_pdf_techbook.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Ruby</category>
            
            
            <pubDate>Mon, 30 Apr 2007 22:44:39 -0500</pubDate>
        </item>
        
        <item>
            <title>Finding a Ruby IDE</title>
            <description><![CDATA[<p>
  Recently I've spent some time revisiting and learning more about Ruby on
  Rails. In doing so I wanted a decent editor to work with.&nbsp; This article
  is about my "adventure" in finding an editor and/or IDE that I could use in
  exploring and learning Ruby and Ruby on Rails and ultimately what I ended up
  selecting.<br/>
</p>

<p>
  Everything I read online talked about
  <a href="http://macromates.com/" title="TextMate">TextMate</a> the editor of
  choice for Mac Ruby developers. I have a Windows machine so I didn't have that
  option. I decided to stick close to home by seeing if IntelliJ (my favorite
  Java editor) had a plug-in that supported Ruby. At the time no such plug-in
  existed. I gave SciTE and FreeRIDE (the editors that come with the Ruby
  distribution) a spin but wanted something a little closer to what I was use to
  in a Java IDE. I remember hearing something about RadRails, a Ruby IDE based
  on Eclipse. I was familiar enough with Eclipse so I decided to use that for my
  dabbling. I used this for a while and it was OK for what I was doing.<br/>
</p>

<p>
  In the meantime I came across a Windows TextMate-like editor called "e". I
  first installed a beta version of "e" which stands for the
  "<a href="http://e-texteditor.com/" title="E Text Editor">E Text Editor</a> ".
  I spent some time trying to make this editor work for me. I wanted to see what
  all the excitement was about in the TextMate world, even if it was on Windows
  :-) . To use "e" I first needed an updated installation of
  <a href="http://www.cygwin.com" title="cygwin">cygwin</a> since "e" relies on
  cygwin to function. I wasn't overly pleased that "e" relied on cygwin to be a
  functional editor. Nevertheless I installed a recent copy of cygwin and was up
  and running with "e". "e" is in beta and with beta software comes annoyances
  and partially functional software. I really wanted to make this editor
  work.&nbsp; However, I ran in to a few bugs that prohibited me from using "e"
  and caused me to resume using RadRails. About this time, the IntelliJ folks
  released a Ruby plug-in.
</p>

<p>
  The IntelliJ plug-in worked fairly well for what I needed. I could use it in
  an environment that I was very familiar with and was happy to be "home".
  Initially I experienced some minor bugs. The biggest problem I had was the
  plug-in can only be used in IntelliJ 6+ and I currently run 5.1 and wasn't
  prepared to upgrade. Unlike other editors I had looked at IntelliJ is
  relatively more expensive.&nbsp; After my 30 day license expired, I headed
  back to RadRails, but then I ran in to this blog post about the future of
  RadRails:
</p>

<blockquote>
<p>
  "<font face="Tahoma, sans-serif"><font color="#1f1f1f">The bottom line to all
  of this is that Matt and I can't provide the same kind of commitment that we
  once could. Like or not, RadRails is not a business. We've been working our
  asses off on a start-up for the past few months and RadRails has suffered as a
  result. I wish things were different and we could sit back and work on open
  source all day but that is just not the reality anymore.</font></font>"
</p>
</blockquote>

<p>
  I wanted to use software where I felt there was community support. I continued
  my search to see what else was available. I came across
  <a href="http://intype.info/home/index.php" title="InType">InType</a>, a very
  basic editor that is suppose to be TextMate-like, however, at the time of the
  writing they were still in an alpha version and didn't seem to have much
  momentum. At the time I used the software it was still very immature (e.g. no
  tab support though you can open multiple windows). Then one day I read a blog
  entry about Ruby support in NetBeans. IÃ•d always associated NetBeans with the
  so-so Java IDE currently produced by Sun.
</p>

<p>
  I downloaded a
  <a href="http://wiki.netbeans.org/wiki/view/MilestoneDownloads" title="milestone release">milestone
  release</a> of NetBeans release 6 and installed support for Ruby and Ruby on
  Rails. Almost instantly I was wowed by their support for Ruby and Rails. I had
  no trouble becoming productive with the IDE and have been happy with the
  product since.&nbsp; Current features include:
</p>
<ul>
  <li>
    Code completion
  </li>
  <li>
    Occurrence highlighting
  </li>
  <li>
    Integrated documentation pop-ups for Ruby API calls
  </li>
  <li>
    Parameter completion
  </li>
  <li>
    Mongrel support
  </li>
  <li>
    Rake migrations
  </li>
  <li>
    And much
    <a href="http://wiki.netbeans.org/wiki/view/RubyRecentChanges" title="more">more</a>
  </li>
</ul>

<p>
  Additionally, NetBeans supports development in either the reference
  implementation of Ruby or in
  <a href="http://jruby.codehaus.org/" title="JRuby">JRuby</a>, a Java
  implementation of the Ruby interpreter.&nbsp; Most recently the NetBeans folks
  have begun adding
  <a href="http://blogs.sun.com/tor/entry/ruby_screenshot_of_the_week7" title="support">support</a>
  for TextMate bundles. They have also created a
  <a href="http://deadlock.nbextras.org/hudson/job/ruby/" title="stripped down version">stripped
  down version</a> of the IDE that is strictly for Ruby coding (though this
  still seems a little rough around the edges). As you can see the NetBeans
  folks are really putting forth a great deal of effort to create a solid,
  robust IDE for creating Ruby and Ruby on Rails applications. While the
  RadRails IDE is now supported by
  <a href="http://www.aptana.com/" title="Aptana">Aptana</a> and
  <a href="http://www.jetbrains.com/idea/nextversion/" title="IntelliJ 7">IntelliJ
  7</a> will include built in Ruby support (release expected by the end of the
  year), NetBeans has made a big leap ahead of the rest of the pack and nothing
  appears to be getting in their way. For now NetBeans is the choice for me when
  doing Ruby development.
</p>
<p>
<strong>Update: </strong>I forgot to mention this recent <a href="http://tnlessone.wordpress.com/2007/02/28/ruby-rails-ide-comparison-idea-netbeans-radrails/">IDE comparison</a> of NetBeans, IntelliJ and RadRails.
</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/jim_clark/finding_a_ruby_ide.html</link>
            <guid>http://www.nearinfinity.com/blogs/jim_clark/finding_a_ruby_ide.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Ruby</category>
            
            
            <pubDate>Mon, 16 Apr 2007 21:49:33 -0500</pubDate>
        </item>
        
        <item>
            <title>IntelliJ Type Renderers</title>
            <description><![CDATA[<p>
When debugging in <a href="http://www.jetbrains.com/idea/">IntelliJ</a> you may need to inspect byte arrays as these byte arrays may contain meaningful text.  Out of the box individual byte array values will be rendered as numeric byte values.   This makes it difficult to decipher what it is you're debugging.
</p>

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="pre_renderer.gif" src="http://www.nearinfinity.com/blogs/pre_renderer.gif" class="mt-image-none" style="" height="252" width="260" /></span><br /> 

<p>
Fortunately IntelliJ gives a way to customize your data views when debugging.  The way to handle this is create a custom Type Renderer.  While inspecting values during a debug session, in the Frame tab right click and select "Customize Data Views...".  A dialog will appear, select the Type Renderers tab.  IntelliJ allows you to create a renderer for objects of a particular type.  Apply renderer to a byte[] and use the expression "new String(this)".  
</p>

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="customize_data_views.gif" src="http://www.nearinfinity.com/blogs/customize_data_views.gif" class="mt-image-none" style="" height="578" width="665" /></span><br />

<p><br />
</p><p>This will render the byte array as a String:
</p>

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="post_renderer.gif" src="http://www.nearinfinity.com/blogs/post_renderer.gif" class="mt-image-none" style="" height="243" width="265" /></span>

<p>
For cases when you don't want this type renderer enabled, IntelliJ allows you to disable the renderer by unchecking the checkbox next to the renderer name.
</p><div><br /></div><div><br /></div><div><br /></div>]]></description>
            <link>http://www.nearinfinity.com/blogs/jim_clark/intellij_type_renderers.html</link>
            <guid>http://www.nearinfinity.com/blogs/jim_clark/intellij_type_renderers.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Java</category>
            
            
            <pubDate>Wed, 04 Apr 2007 14:30:27 -0500</pubDate>
        </item>
        
        <item>
            <title>Thumbnail Generation Gotchas</title>
            <description><![CDATA[<p>
    For a recent release of our software we had a requirement to generate and store thumbnail images.
    We have documents that come in to our system with image attachments and we need to generate a
    thumbnail image for each of the attachments that have a supported MIME type (gif, jpg, and png).
    When I signed up for this assignment I thought it was a good opportunity to re-learn JavaÃ•s image APIs (itÃ•s been
    almost seven years since doing any Swing or AWT work!). A lot of information is available on the web for generating
    thumbnail images, however, the information is scattered and there is more than one way to perform this task. Additionally, there are several gotchas 
    that I experienced rather than reading about.  Hopefully this article will get you started in the right direction and help you avoid
    some of the problems I faced.
</p>


<h2>Scaling Images</h2>

<p>
    Before reading and writing images, I first needed to figure out how to actually scale an image, i.e. take an
    original image and size it to an appropriate thumbnail size. Digging around the AWT package and the Image class
    I found the <code>java.awt.Image.getScaledInstance</code> method. Piece of cake, just do something like:
</p>

<pre><code>
    Image scaledInstance = image.getScaledInstance(thumbWidth, thumbHeight, hint);
</code></pre>

<p>
    This worked fine and I used it for a couple of weeks when one of my <a
        href="http://www.nearinfinity.com/blogs/page/jharwig">coworkers</a>
    pointed out that this was no longer the best way to scale images
    (see Bug <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6196792">6196792</a>) Instead, use the 2D
    Graphics API and an
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/geom/AffineTransform.html">AffineTransform</a> for a better solution.
</p>

<pre><code>
public static BufferedImage getThumbnail(BufferedImage image, 
                                         int maxThumbWidth, 
                                         int maxThumbHeight, 
                                         RenderingHints hints)
{
   BufferedImage thumbnail = null;
   if(image != null)
   {
       AffineTransform tx = new AffineTransform();
       // Determine scale so image is not larger than the max height and/or width. 
       double scale = scaleToFit(image.getWidth(), 
                                 image.getHeight(), 
                                 maxThumbWidth, maxThumbHeight);
                 
       tx.scale(scale, scale);

       double d1 = (double) image.getWidth() * scale;
       double d2 = (double) image.getHeight() * scale;
       thumbnail = new BufferedImage(
               ((int) d1) < 1 ? 1 : (int)d1,  // don't allow width to be less than 1
               ((int) d2) < 1 ? 1 : (int)d2,  // don't allow height to be less than 1
               image.getType() == BufferedImage.TYPE_CUSTOM ? 
                                  BufferedImage.TYPE_INT_RGB : image.getType());
       Graphics2D g2d = thumbnail.createGraphics();
       g2d.setRenderingHints(hints);
       g2d.drawImage(image, tx, null);
       g2d.dispose();
   }
   return thumbnail;
}


private static double scaleToFit(double w1, double h1, double w2, double h2) {
        double scale = 1.0D;
        if (w1 > h1) {
            if (w1 > w2)
                scale = w2 / w1;
            h1 *= scale;
            if (h1 > h2)
                scale *= h2 / h1;
        } else {
            if (h1 > h2)
                scale = h2 / h1;
            w1 *= scale;
            if (w1 > w2)
                scale *= w2 / w1;
        }
        return scale;
    }

    </code>
</pre>

<p>
    Using this code I was able to scale an image, i.e. create a thumbnail, and now I needed to save it.
</p>


<h2>Storing Thumbnails</h2>

<p>
    Since I was working with J2SE 1.4, which only allows for creating images in JPEG and PNG formats, we decided to use the JPEG format for
    thumbnails for its smaller file size.  
    I needed a way to write my thumbnail to an output stream since we have a separate API for storing files. Fortunately
    the <code>javax.imageio.ImageIO</code> package provided
    an easy way to create JPEG images and put the image in to an OutputStream:
</p>

<pre>
    ImageIO.write(myImage, "jpg", myOutputStream);
</pre>

<p>
    I incorporated my changes in to the build and left for a week of training, everything seem to be working ok. Upon returning I found out that
    thumbnails were "killing" our system.
    Naturally, I questioned, "are you sure itÃ•s thumbnails causing the problem?" ItÃ•s just image creation. Sure enough, the problem was caused by
    thumbnail generation.  It turns out the garbage collector went in to full GC mode when thumbnails were being created, specifically when hundreds 
    or thousands of thumbnails were being generated. Ugh, back to the drawing board.
</p>

<p>After a little research, it was discovered that there are memory leaks in SunÃ•s ImageIO JPEG libraries
    (<a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5015137">Bug 5015137</a>
    and <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4827358">Bug 4827358</a>).
    As our system was creating hundreds of thumbnails, everything else came to a screeching halt thanks to garbage
    collection. What to do, what to do?
</p>

<p>
    Supposedly these bugs are fixed in J2SE 1.5, however, upgrading wasn't an option.
</p>
<p>
    One solution we looked at was creating thumbnails as PNG files. Fine, this works, no problems with performance.
    YouÃ•ll just need to go out and buy a few extra hard drives. I was finding the PNGs to be 4, 5, 6 times larger than
    JPEGs. I looked at ways to compress the PNGs via Java but didnÃ•t have much luck getting them down to a reasonable
    size.
</p>

<p>
    We also talked about having the thumbnail creation occur offline after the document was brought in to our system.
    This seemed more complicated than we wanted to make it. Plus we were running out of time as the code deadline was
    approaching.
</p>

<p>        
Next a coworker sent a snippet of code, for encoding images to JPEG, that talked directly to <code>com.sun</code>
JPEG classes.  This always seemed a no-no, i.e. Sun says: <em>"Note that the classes in the <code>com.sun.image.codec.jpeg</code> 
package are not part of the core Java APIsÃ‰".</em>
Since we werenÃ•t planning to upgrade the JDK any time soon we went with this approach for writing JPEGs.
</p>
        
<pre>
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(myByteArrayOutputStream);
    JPEGEncodeParam encodeParams = encoder.getDefaultJPEGEncodeParam(myImage);
    encodeParams.setQuality(0.8F, false);
    encoder.setJPEGEncodeParam(encodeParams);
    encoder.encode(myImage);
</pre>

<p>
    Everyone was happy; we could create JPEG thumbnails by circumventing the ImageIO API and talking directly to the
    com.sun classes. UntilÃ‰
</p>

<h2>Reading Images</h2>

<p>
    I noticed that certain thumbnails werenÃ•t being rendered correctly; rather they were rendered as black rectangles.
</p>
        
<div style="background: black;height: 75px;width:100px"></div>        

<p>
    Now what? Was this something to do with the usage of the <code>JPEGImageEncoder</code>, i.e. talking directly to the <code>com.sun</code> classes? 
    After a little research it turns out the problem existed previously when directly using <code>ImageIO</code> to encode and write images.
    Therefore, no new problems were introduced. It seemed to be a problem only with GIF files. I ran a couple of tests on
    Windows (dev environment) using my test GIFs and
    they worked fine. I tested animated GIF files on Windows and they worked correctly. I tested the animated GIFs on Solaris.
    These images were being rendered as black images. The animated GIF images that were "thumbnailed" on Solaris were not 
    created correctly.  I was now able to repeat the problem.
</p>

<p>
    To read images from the file system, the images I would create thumbnails from, I was using the AWT tookit:
</p>

<pre>
    Image image = Toolkit.getDefaultToolkit().createImage(myFileBytes);
</pre>

<p>
    Unlike Windows, the Solaris toolkit apparently didnÃ•t know how to handle images that were made up of multiple images (GIF89a). I
    needed a way to create images, in my case from a byte array, that didn't result in a black image. Back to the ImageIO class. Turns out they have a <code>read</code>
    method that can take an InputStream
</p>

<pre>
    image = ImageIO.read(new ByteArrayInputStream(myImageByteArray));
</pre>

<p>
    However, I was a little leery of the ImageIO class due to the problems I had seen with the <code>write</code> method.
    I did find a bug related to <code>ImageIO.read</code> method (<a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4867874">Bug 4867874</a>),
    but it pertained to JPEGs.
    I decided to use <code>ImageIO.read</code> for GIF files and continue using the AWT toolkit for JPEGs and other types.  This was a fix
    for our black image problem.
</p>

<p>
    It seems as if our thumbnail processing is working as expected and we havenÃ•t seen noticeable degradation in
    performance or the black image problem.
</p>

<p>
    If youÃ•ll be doing image processing, such as thumbnail creation, make sure your application can handle the
    processing requirements.
    Test a worse case scenario, e.g. create 1000 thumbnails. Test with many different image samples with different image
    formats (e.g. animated gifs)
    and sizes (large image files). Unfortunately you'll have to actually view the images to verify expected output, but now you are 
    hopefully aware of some of the issues surrounding the generation of thumbnails using the ImageIO APIs and the AWT toolkit.
</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/jim_clark/thumbnail_generation_gotchas.html</link>
            <guid>http://www.nearinfinity.com/blogs/jim_clark/thumbnail_generation_gotchas.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Java</category>
            
            
            <pubDate>Tue, 26 Dec 2006 15:21:48 -0500</pubDate>
        </item>
        
    </channel>
</rss>
