title: Java bitmap font: blitting 1-bit image with different colors
body: <p>I'd like to implement a simple bitmap font drawing in Java AWT-based application. Application draws on a <code>Graphics</code> object, where I'd like to implement a simple algorithm:</p>
  
  <p>1) Load a file (probably using <code>ImageIO.read(new File(fileName))</code>), which is 1-bit PNG that looks something like that:</p>
  
  <p><img src="https://i.stack.imgur.com/5taV1.png" alt="8*8 bitmap font"></p>
  
  <p>I.e. it's 16*16 (or 16*many, if I'd like to support Unicode) matrix of 8*8 characters. Black corresponds to background color, white corresponds to foreground.</p>
  
  <p>2) Draw strings character-by-character, blitting relevant parts of this bitmap to target <code>Graphics</code>. So far I've only succeeded with something like that:</p>
  
  <pre><code>    int posX = ch % 16;
      int posY = ch / 16;
  
      int fontX = posX * CHAR_WIDTH;
      int fontY = posY * CHAR_HEIGHT;
  
      g.drawImage(
              font,
              dx, dy, dx + CHAR_WIDTH, dy + CHAR_HEIGHT,
              fontX, fontY, fontX + CHAR_WIDTH, fontY + CHAR_HEIGHT,
              null
      );
  </code></pre>
  
  <p>It works, but, alas, it blits the text as is, i.e. I can't substitute black and white with desired foreground and background colors, and I can't even make background transparent.</p>
  
  <p>So, the question is: is there a simple (and fast!) way in Java to blit part of one 1-bit bitmap to another, colorizing it in process of blitting (i.e. replacing all 0 pixels with one given color and all 1 pixels with another)?</p>
  
  <p>I've researched into a couple of solutions, all of them look suboptimal to me:</p>
  
  <ul>
  <li>Using a custom colorizing <a href="http://download.oracle.com/javase/6/docs/api/java/awt/image/BufferedImageOp.html" rel="nofollow noreferrer">BufferedImageOp</a>, as outlined in <a href="https://stackoverflow.com/questions/23763/colorizing-images-in-java">this solution</a> - it should work, but it seems that it would be very inefficient to recolorize a bitmap before every blit operation.</li>
  <li>Using multiple 32-bit RGBA PNG, with alpha channel set to 0 for black pixels and to maximum for foreground. Every desired foreground color should get its own pre-rendered bitmap. This way I can make background transparent and draw it as a rectangle separately before blitting and then select one bitmap with my font, pre-colorized with desired color and draw a portion of it over that rectangle. Seems like a huge overkill to me - and what makes this option even worse - it limits number of foreground colors to a relatively small amount (i.e. I can realistically load up and hold like hundreds or thousands of bitmaps, not millions)</li>
  <li>Bundling and loading a custom font, as outlined in <a href="https://stackoverflow.com/questions/5902229/custom-fonts-in-java">this solution</a> could work, but as far as I see in <a href="http://download.oracle.com/javase/6/docs/api/java/awt/Font.html#createFont(int,%20java.io.InputStream)" rel="nofollow noreferrer">Font#createFont</a> documentation, AWT's <code>Font</code> seems to work only with vector-based fonts, not with bitmap-based.</li>
  </ul>
  
  <p>May be there's already any libraries that implement such functionality? Or it's time for me to switch to some sort of more advanced graphics library, something like <a href="http://lwjgl.org/" rel="nofollow noreferrer">lwjgl</a>?</p>
  
  <h2>Benchmarking results</h2>
  
  <p>I've tested a couple of algorithms in a simple test: I have 2 strings, 71 characters each, and draw them continuously one after another, right on the same place:</p>
  
  <pre><code>    for (int i = 0; i &lt; N; i++) {
          cv.putString(5, 5, STR, Color.RED, Color.BLUE);
          cv.putString(5, 5, STR2, Color.RED, Color.BLUE);
      }
  </code></pre>
  
  <p>Then I measure time taken and calculate speed: string per second and characters per second. So far, various implementation I've tested yield the following results:</p>
  
  <ul>
  <li>bitmap font, 16*16 characters bitmap: 10991 strings / sec, 780391 chars / sec</li>
  <li>bitmap font, pre-split images: 11048 strings / sec, 784443 chars / sec</li>
  <li>g.drawString(): 8952 strings / sec, 635631 chars / sec</li>
  <li>colored bitmap font, colorized using LookupOp and ByteLookupTable: 404 strings / sec, 28741 chars / sec</li>
  </ul>